[
https://issues.apache.org/jira/browse/DIRMINA-391?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Trustin Lee resolved DIRMINA-391.
---------------------------------
Resolution: Won't Fix
It's a known issue and that's why we suggest to use non-direct buffers.
Current JVM implementation is very unstable in managing direct buffers. MINA
committers concluded it's a flaw of JVM and JVM need to provide a proper
management of the buffers. Consequently, we switched the default buffer type
to 'heap' in 2.0-SNAPSHOT and removed acquire() and release() method for better
performance.
Until the JVM issue is resolved, please use non-direct buffers only and use
SimpleByteBufferAllocator for maximum performance and stability.
> Memory Leaks with SocketChannel.write
> -------------------------------------
>
> Key: DIRMINA-391
> URL: https://issues.apache.org/jira/browse/DIRMINA-391
> Project: MINA
> Issue Type: Bug
> Components: Transport
> Affects Versions: 1.0.4, 1.1.1, 2.0.0-M1
> Environment: All versions of JDK
> Reporter: Kenji Hollis
>
> There is a known issue with Java when using the "SocketChannel.write"
> function with a standard ByteBuffer. Memory gets leaked slowly as the system
> uses a DirectByteBuffer for each write that occurs in the system. This may
> not cause an issue with systems that are under a small load, but systems
> under heavy load will notice a memory issue, and will eventually crash with
> little or no notice.
> The way to get around this is to allocate a ByteBuffer that is allocated
> using "allocateDirect" first, then writing to that buffer, and clearing it
> out when required. This way, you only have a single ByteBuffer that is being
> written to, and written from. When the JDK sees that you are writing data
> from a DirectByteBuffer, it does not allocate its own DirectByteBuffer - it
> outputs the data from yours. This will get around the memory allocation
> issue.
> So, to summarize, here's what needs to be done:
> On a write with a ByteBuffer that uses allocateDirect, this is what worked
> for us:
> --- Cut code ---
> private final ByteBuffer directOutputBuffer =
> ByteBuffer.allocateDirect(40960);
> public int write(ByteBuffer buf) {
> directOutputBuffer.clear();
> directOutputBuffer.put( buf.array() );
> directOutputBuffer.flip();
> return socket.write( directOutputBuffer );
> }
> --- End cut ---
> This will always use the allocated stack memory of 40K (which can be lower,
> depending on requirements of the OS based on the max output buffer size). If
> you simply say "socket.write( buf )", you will notice after a short amount of
> time, memory usage will increase, and you will eventually get a Java
> exception that shows "out of memory".
> This is critical enough that it should be fixed, but as I am not a
> contributing member (yet), I am not sure about how to tackle this. I believe
> using a pool of DirectByteBuffer objects will fix the issue, but keep in mind
> that if a pool is created for these, since the pool is a permanent allocation
> of memory, you -cannot- shrink the size of the allocated pool: you must use a
> static size. The problem here will be determining which pool is in use.
> I can throw together a test case for you guys if you want to show this issue
> if you would like. Please see:
> http://www.velocityreviews.com/forums/t147788-nio-outofmemoryexception.html
> for more information on the subject. We had this issue, and have seen a fix
> with using this suggestion.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.