United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 4820023 (bf) Decrease memory footprint of direct buffers
4820023 : (bf) Decrease memory footprint of direct buffers

Details
Type:
Enhancement
Submit Date:
2003-02-18
Status:
Open
Updated Date:
2005-01-26
Project Name:
JDK
Resolved Date:
Component:
core-libs
OS:
solaris,linux
Sub-Component:
java.nio
CPU:
x86,generic
Priority:
P5
Resolution:
Unresolved
Affected Versions:
1.4.1,1.4.2,5.0u5
Targeted Versions:

Related Reports
Duplicate:

Sub Tasks

Description

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) 
======================================================================

                                    

Comments
EVALUATION

Direct buffers are page-aligned in Sun's implementation so that such buffers
can take part in zero-copy transfer protocols whenever possible.  We could
loosen this restriction by, say, only page-aligning buffers over a certain
size (1KB?).

I'm not sure this is advisable however.  Tiny direct buffers would still not
be cheap -- they'd still be managed by the GC, and they'd still only be freed
after their corresponding Java-level buffer objects are freed.

As to the specific application described by the submitter, I'm surprised that
working with OpenGL requires large numbers of tiny direct buffers.  We've done
our own OpenGL binding in-house and have not run into this problem.

-- ###@###.### 2003/2/18
                                     
184-11-02 0



Hardware and Software, Engineered to Work Together