Name: rmT116609 Date: 02/18/2003
FULL PRODUCT VERSION :
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)
FULL OPERATING SYSTEM VERSION :
RedHat 8.0:
Linux ip172.kmk.kollegie.dk 2.4.18-24.8.0 #1 Fri Jan 31
07:28:55 EST 2003 i686 athlon i386 GNU/Linux
glibc-2.2.93-5
ADDITIONAL OPERATING SYSTEMS :
Windows XP
A DESCRIPTION OF THE PROBLEM :
I'm currently developing a java game that makes extensive
use of direct buffers to communicate with OpenGL. Indirect
buffers can't efficiently be used for that purpose because
the jvm might move indirect buffers between calls to the
native opengl wrapper.
The problem is when allocating alot of small direct
buffers the memory overhead has a serious impact on total
application memory usage. To see this, compile the
attached program and watch 'top' in linux while the
program sleeps. 100000 direct buffers all of size 1 byte
is allocated giving a theoretical memory size of 100k.
However, on my system, 'top' shows a memory usage of about
400 MB! This hints that direct buffers are allocated in OS
memory pages, each 4k big on my system.
To me, this seems totally unacceptable, and forces me to
do my own memory management by allocating one large chunk
and slice it up as needed. A task that the jvm could just
as well do (like the C malloc), by letting direct buffers
share pages.
I'm submitting this as a RFE, as this behaviour is not a
bug given the wording from the docs:
"The contents of direct buffers may reside outside of the
normal garbage-collected heap, and so their impact upon
the memory footprint of an application might not be
obvious. It is therefore recommended that direct buffers
be allocated primarily for large, long-lived buffers that
are subject to the underlying system's native I/O
operations."
(From the javadocs on java.nio.ByteBuffer)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile and run the included program
2. watch memory usage of the program. This _isn't_ the
normal java heap usage, but the memory usage as reported
by the OS. e.g. 'top' on linux.
EXPECTED VERSUS ACTUAL BEHAVIOR :
I'd expect the granularity of direct buffers to be finer
than what seems to be one page of mem (4k)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.nio.*;
public class TestMem {
public static void main(String[] args) {
ByteBuffer[] bufs = new ByteBuffer[100000];
for (int i = 0; i < bufs.length; i++)
bufs[i] = ByteBuffer.allocateDirect(1);
try {
Thread.sleep(60000);
} catch (Exception e) {
e.printStackTrace();
}
// Free memory used by the buffers
bufs = null;
System.gc();
try {
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
If one need direct buffers (like me), allocate one large
chunk and slice() it up in smaller buffers. If not, use
indirect (heap-allocated) buffers or normals java arrays
(Review ID: 181453)
======================================================================
|