[Red5commits] [1556] Fixed OutOfMemoryError? when playing large FLV files. Originally, FLVReader will
sgong
luke at codegent.com
Wed Jan 24 10:53:36 EST 2007
Fixed OutOfMemoryError? when playing large FLV files. Originally, FLVReader will buffer the whole file into an
allocated ByteBuffer?. If the file is large, this operation will fill the available memory up. Now a new static
member 'maxBufferSize' is used as a threshold for buffer usage. The default is 10,000,000 bytes and can be configured
in red5-common.xml. And another improvement is that buffer option can be disabled when the buffer type is none of
'auto', 'direct' 'heap'.
Timestamp: 11/18/06 04:24:19 EST (2 months ago)
Change: 1556
Author: sgong
Files (see diff or trac for details):
java/io/trunk/src/org/red5/io/flv/impl/FLV.java
java/io/trunk/src/org/red5/io/flv/impl/FLVReader.java
Trac: http://mirror1.cvsdude.com/trac/osflash/red5/changeset/1556
Index: /java/io/trunk/src/org/red5/io/flv/impl/FLV.java
===================================================================
--- /java/io/trunk/src/org/red5/io/flv/impl/FLV.java (revision 1519)
+++ /java/io/trunk/src/org/red5/io/flv/impl/FLV.java (revision 1556)
@@ -38,5 +38,4 @@
import org.red5.server.api.cache.ICacheStore;
import org.red5.server.api.cache.ICacheable;
-import org.red5.server.cache.CacheableImpl;
/**
@@ -175,5 +174,5 @@
fileData = reader.getFileData();
// offer the uncached file to the cache
- if (cache.offer(fileName, new CacheableImpl(fileData))) {
+ if (cache.offer(fileName, fileData)) {
if (log.isDebugEnabled()) {
log.debug("Item accepted by the cache: " + fileName);
Index: /java/io/trunk/src/org/red5/io/flv/impl/FLVReader.java
===================================================================
--- /java/io/trunk/src/org/red5/io/flv/impl/FLVReader.java (revision 1519)
+++ /java/io/trunk/src/org/red5/io/flv/impl/FLVReader.java (revision 1556)
@@ -88,4 +88,9 @@
private static String bufferType = "auto"; //Default
+ private static int maxBufferSize = 0;
+ private static volatile int bufferUsed = 0;
+
+ private boolean useBuffer = false;
+
FLVReader() {}
@@ -105,22 +110,41 @@
log.debug("Mapped file capacity: " + mappedFile.capacity() + " Channel size: " + channel.size());
}
- switch (bufferType.hashCode()) {
- case 3198444: //heap
- //Get a heap buffer from buffer pool
- in = ByteBuffer.allocate(mappedFile.capacity(), false);
- break;
- case -1331586071: //direct
- //Get a direct buffer from buffer pool
- in = ByteBuffer.allocate(mappedFile.capacity(), true);
- break;
- case 3005871: //auto
- default:
- //Let MINA choose
- in = ByteBuffer.allocate(mappedFile.capacity());
- }
- //drop in the file
- in.put(mappedFile);
- //prepare the buffer for access
- in.flip();
+ int bufferTypeHash = bufferType.hashCode();
+ if (bufferTypeHash == 3198444 ||
+ bufferTypeHash == -1331586071 ||
+ bufferTypeHash == 3005871) {
+ synchronized (FLVReader.class) {
+ if (bufferUsed + mappedFile.capacity() <= maxBufferSize) {
+ bufferUsed += mappedFile.capacity();
+ useBuffer = true;
+ }
+ }
+ }
+ in = null;
+ if (useBuffer) {
+ switch (bufferTypeHash) {
+ case 3198444: //heap
+ //Get a heap buffer from buffer pool
+ in = ByteBuffer.allocate(mappedFile.capacity(), false);
+ break;
+ case -1331586071: //direct
+ //Get a direct buffer from buffer pool
+ in = ByteBuffer.allocate(mappedFile.capacity(), true);
+ break;
+ case 3005871: //auto
+ //Let MINA choose
+ in = ByteBuffer.allocate(mappedFile.capacity());
+ break;
+ default:
+ break;
+ }
+ }
+ if (in != null) {
+ //drop in the file
+ in.put(mappedFile);
+ in.flip();
+ } else {
+ in = ByteBuffer.wrap(mappedFile);
+ }
if (log.isDebugEnabled()) {
log.debug("Direct buffer: " + in.isDirect() + " Read only: " + in.isReadOnly() + " Pooled: " + in.isPooled());
@@ -166,4 +190,12 @@
public static void setBufferType(String bufferType) {
FLVReader.bufferType = bufferType;
+ }
+
+ public static int getMaxBufferSize() {
+ return maxBufferSize;
+ }
+
+ public static void setMaxBufferSize(int maxBufferSize) {
+ FLVReader.maxBufferSize = maxBufferSize;
}
@@ -313,11 +345,23 @@
synchronized public void close() {
log.debug("Reader close");
+ if (in != null) {
+ if (useBuffer) {
+ int bufferTypeHash = bufferType.hashCode();
+ if (bufferTypeHash == 3198444 ||
+ bufferTypeHash == -1331586071 ||
+ bufferTypeHash == 3005871) {
+ synchronized (FLVReader.class) {
+ if (mappedFile != null) {
+ bufferUsed -= mappedFile.capacity();
+ }
+ }
+ }
+ }
+ in.release();
+ in = null;
+ }
if (mappedFile != null) {
mappedFile.clear();
mappedFile = null;
- }
- if (in != null) {
- in.release();
- in = null;
}
if (channel != null) {
Note:
Diffs are chopped if more than 25k.
This is to get past the limit on the mailing list.
More information about the Red5commits
mailing list