Shaoping Zhou <[EMAIL PROTECTED]> wrote:
>Yes, your points and examples are well-taken.
>
>What I tried to explain in my earlier response is that, if your program does
>have to process a large number of objects, say 2500 objects and each
>object has
>a size of 20KB, then VM just need to have 2500*20KB = 50 MB. "out of memory"
>is exactly what I encountered when I run my servlet using JDK 1.2 on a Sparc
>machine, and I cannot just do anything about it except to increase the initial
>and maximum memory for Java VM. I simply could not figure out a way to
>programatically reduce the memory usage. Those 2500 objects after creation
>just stayed around until VM decide to have mercy and do some garbage
>collection.
>
>Well, I could use Runtime class methods to explicitly kick off garbage
>collection, but still no control of how much to reclaim. It does help a bit
>for reducing the occupied memory by Java VM.
>
>But, then maybe there is a way to dispose those 2500 data objects ?
>
>regards,
Either I don't understand quite what you're doing, or this is a bug in your
program or in the JVM. Maybe you really do need to allocate 50MB at once to
do something (e.g., load a big image file into memory). On the other hand,
you may just need a much smaller working set size, say 1MB, but the total
memory allocated over the lifetime of the task might reach 50MB. The JVM
garbage collector will reclaim any object that is not referenced by another
object. When the reclamation will happen is not specified, but it should
certainly happen if the VM is unable to satisfy a pending memory allocation
request.
Say you do this:
void foo()
{
for (int i = 0; i < 2500; ++i)
byte[] dummy = new byte[20000];
}
then your JVM should reuse the memory because you only have 20K allocated
at any one time. But if you do this:
void foo()
{
Vector v = new Vector();
for (int i = 0; i < 2500; ++i)
v.addElement(new byte[20000]);
}
then your VM will only deallocate the memory when you exit the method body
and the vector becomes eligible for garbage collection, thus gobbling up
the full 50MB. On the other hand, you can do something like:
void foo()
{
for (int j = 0; j < 50; ++j) {
Vector v = new Vector();
for (int j = 0; j < 50; ++j)
v.addElement(new byte[20000]);
}
}
now you are only using 50*20K=1MB at a time. You might still end up
allocating 50MB (and your process size and the Runtime library will
indicate this), but the VM will be able to reuse memory if the OS or the
startup options limit the process size to, say, 16MB.
To make any arbitrary object eligible for GC you just need to remove all
references to that object. Sometimes this is as simple as exiting an
enclosing block or setting to null a single class member variable
referencing the object.
>From your description it sounds like you only need a fraction of the full
50MB at a time, but it turns out that somehow you end up gobbling up all of
this memory. This means that either the VM/GC is not garbage collecting or
that your program is holding on to references to the objects which prevent
the GC from freeing the memory.
JDK 1.1 had a verbose GC option "-verbosegc" that would print a message
whenever the GC did its thing. JDK1.2 uses "-verbose:gc". Try turning these
on to see what the VM/GC are doing.
-- Ari Halberstadt mailto:[EMAIL PROTECTED] <http://www.magiccookie.com/>
PGP public key available at <http://www.magiccookie.com/pgpkey.txt>
----------------------------------------------------------------
To subscribe: [EMAIL PROTECTED]
To unsubscribe: [EMAIL PROTECTED]
Archives and Other: <http://www.working-dogs.com/>
Problems?: [EMAIL PROTECTED]