I would like to better understand my application and specifically its memory footprint.
I do understand the concepts of garbage-collection and I am aware, that there will always be a certain amount of dead objects in the heap, however, I would like to minimize this amount such that monitoring with JConsole (or JVisualVM) provides me with some information about the currently required (not occupied) space.
Is there any way to configure an existing garbage-collector (e.g. G1GC) in the SunVM such that (at the cost of responsiveness and runtime) the amount of dead objects in the heap is minimized?
Clarification
To be more clear about my objectives: My application is non-interactive so the memory-footprint over time is more or less the same between two runs. I want to determine the minimum required heap space and the influence, code changes have on that footprint. The output from JConsole is not really helping here because of the dead objects. I also want to know, whether my peak-memory really is an outstanding peak at one point in time or whether it is streched over time. This is why reducing the Xmx until I reach a OOME is not what gets me there.
Also: I’m talking about use during developer tests, not the use in production here. In production, througput and performance are – of course – more important than a more realistic memroy-footprint.
If you want to know the total amount of memory that your application is using you must monitor it for quite a long time. Samples of the heap at random moments of the application:
and then with
jhatnavigate the heap. There are another tools to do so.Doing this you will know what’s on the heap at a moment.
Bear in mind that objects such as
memory mapped filesare not stored in the heap but in the memory.When reaching
OOMtry adding this, and then reading the output to see which objects are actually in the heap:To do so, enable the
GC logand then use a tool such as GCViewer.When you talk about heap, I understand that you are talking about the
tenuredspace. If so, you need to know the average life of objects. And follow some best practices and then do the fine tuning. Also remember that issuing aSystem.gc()does not guarantees that theGCis performed.The thing is that instances goes to
young generation (eden)and when it is full aminor GCis performed. Objects that still reachable are passed to one of the two spaces calledsurvivor. Once this is full that space is dumped intotenured. When full, afull GCexecutes and delete all instances that are not reachable.One thing you can do is to use
primitivesin methods. Those won’t be placed in the heap as their span of life is in the thread stack.The useful parameters are those which tie the size of the
tenured and young generation (eden). These works by ratios. If you are to issue manyGCbear in mind to set a max time forGC stop.Some interesting parameters are:
For example, setting
-XX:NewRatio=3means that the ratio between the young and old generation is 1:3; in other words, the combined size of eden and the survivor spaces will be one fourth of the heap.Anyway I don’t know why you need this requirement. I usually worry only about the
throughputand only care for those parameters when thethroughputis bad.