I am trying to get a full picture of the Runtime Data Area in Java. Especially about the heap and non-heap part.
In the JVM specs the heap part is clearly defined and it consists of the young and old generation. What is unclear to me is the non-heap part. Especially whether the reserved memory of a thread is part of the code cache or not.
Regarding the non-heap part so far I have figured out that:
- Method Area is completely used for the Permanent Generation
- Native Area contains ... ?
I made a diagram of the Runtime Data Area (see the attached file).
For each thread memory is reserved (e.g. by default 512k, or manually defined by the -Xss option). Each thread itself contains the PC, Stack, and Native Method Stack.
The code cache contains compiled and native code and can be set with the options -XX:InitialCodeCacheSize, -XX:ReservedCodeCacheSize, and -XX:+UseCodeCacheFlushing.
Again: is the non-heap separated into either:
- the memory pools PermGen and Code cache
- or PermGen, Threads 1..N, and Code cache ?
Tai Truong wrote:I am trying to get a full picture of the Runtime Data Area in Java. Especially about the heap and non-heap part.
This is probably going to sound like a silly question, but: Why?
Unless you're planning on writing a JVM of your own, this is unlikely to make you a better Java programmer. I also suspect (although I'm not by any means sure) that a lot of the actual mechanics are left up to JVM and gc designers. The JVM spec is just that - a specification - and much of the actual nuts and bolts will be up to the writer/designer, and 'best practise' may well be different for different machines.
If this is just a mental exercise, don't let me put you off; but in 11 years years of writing (and administering) Java, I've never had to worry about the internals to this level. In fact, if I did, I think it would detract from my job.
My two-penn'orth, for what it's worth.
Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
Winston Gutkowski wrote:If this is just a mental exercise, don't let me put you off; but in 11 years years of writing (and administering) Java, I've never had to worry about the internals to this level. In fact, if I did, I think it would detract from my job.
Well in 12 years I have never stopped learning. Like recently with the options of "-Xss" to set the thread size and with "-XX:ReservedCodeCacheSize". This is useful e.g. when you have limited resources (RAM).
Depending on you application you define the max heap size and max PermGen. But also setting the stack size smaller than the default 512k is useful. Question here is: does code cache cover the complete native area?
If so then it is easy to optimize the memory pools and calculate the total memory being used in the JVM: heap + perm gen + code cache.
If not (like thread's stack size is not part of the code cache resp. both share the native area) then it is not so easy to determine the total memory or to optimize the memory pools.
Of course memory and performance optimzations vary on the different JVMs. Like IBM's JVM under Windows outsources the PermGen being part of the native OS cache. etc. etc. etc.
Understanding Java is one thing, understanding JVM is another issue. It is useful for developers and necessary for load tests in QA. Unless "the hammer is the only tool you have, then every problem is a nail" ;).
Tai Truong wrote:Understanding Java is one thing, understanding JVM is another issue. It is useful for developers and necessary for load tests in QA. Unless "the hammer is the only tool you have, then every problem is a nail" ;).
Hmmm. Beg to disagree there. If the only way you can get your program/app to work (or perform adequately) is by faffing around with memory optimization, then I'd suggest that your issues go a lot deeper than simple memory usage; and learning how the Java RDA works is likely to do little more than allow you to provide band-aids to problems.
That said, I'm all in favour of learning, so don't listen to me...