简体   繁体   中英

How does Java manage to use so much memory in Applet mode?

I;ve been writing a Java swing applet that is to be deployed in a browser (which ios pretty normal for applets, granted). It uses Java 2D for

Anyway, I have a test harness for development purposes, which runs it as a desktop app.

Based on exactly the same test data, the Test Harness version has a heap total size 18 Meg; this is based on drawing about 7000 objects on a Java 2D canvas with perhaps 30,000 coordinate pairs, plus other bits and pieces, so an 18 Meg heap is big but just about understandable. Total app size is 40 Meg.

Now I run exactly the same code as an Applet, via IBM Websphere.

The delta in memory for the plug-in rises to about 160Meg! Somehow the same java code is managing to use 10 times the memory.

The old CBM64 programmer in me is not particularly impressed at the first figure - it's an order of magnitude bloated IMO, but the second is amazing - does anyone have a clue what could possibly be using so much memory? I'm looking with VisualVM, and it's helpfully putting things like Object, char[] and String as the memory hogs, none of my classes come close.

Interestingly, Float and Double seem to take up exactly the same amount of memory (16 bytes each.).

My main guess right now is that the data retrieval using SOAP is causing the huge spike in memory use, and for reasons unknown the SOAP XML is being retained instead of GC'd.

Does anyone else out there have a clue as to what is going on here?

Found it - or a bit thereof.

When you use Axis 1.3 to make a SOAP call - to fetch the data in the first place - it doesn't deallocate the SOAP XML until the next call.

Unfortunately, in this case there was only an initial data population call, so Axis was hanging onto ~150Meg of XML. Simple enough workaround, make a second 'empty' call to clear it. All fine once GC'd.

The JVM always allocates a pool of memory that is larger than it needs or is actually likely to be using at any given time. Any external measure of the memory usage of the JVM is likely to be misleading.

The JVM does this for a few fairly sensible reasons:

  • It enables the garbage collector to run more efficiently when it has more space to allocate / move objects about
  • Even if the GC clears some space, it makes sense to keep the space reserved on the assumption that the program is likely to need it again
  • The GC avoids unnecessary work by collecting garbage lazily - unless the GC is forced to perform a collection then old objects can exist on the heap for quite some time. These objects aren't doing any harm - the space can be reclaimed later if needed.

You are probably just seeing the result of this bahaviour. Unless you are actually encountering problems (like OutOfMemoryError - which could suggest you have a memory leak) then don't worry about it.

ps the reason that Float and Double objects both take 16 bytes each is most likely that a) they have an object header and b) they are then padded to ensure cache line / memory addressing alignment. If you pack a lot of floats / doubles in an array then you will find they take 4 and 8 bytes respectively.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM