I want to employ com.sun.management.ThreadMXBean
to do something like this:
long before = threadMxBean.getThreadAllocatedBytes(currentThreadId);
seriousBusiness(); // some calls here
long after = threadMxBean.getThreadAllocatedBytes(currentThreadId);
long allocDiff = after - before; // use for stats or whatever
The question is, what does this method actually return: amount of new memory allocated at the moment of method invocation or the size of allocated objects? To be clear on what difference I mean:
1) Say I allocated a huge array in my seriousBusiness()
call, so a new memory region was allocated for this purpose and getThreadAllocatedBytes
gets incremented by the corresponding value.
2) Some time passed, there was a GC run, that unused array was collected and the memory region is free now.
3) I do some calls again (in the same thread), JVM sees that it doesn't need to allocate new memory and reuses that memory region for the new purpose, which results in getThreadAllocatedBytes
value not growing.
I might not be precise on how does JVM memory management work, but the question should be clear as is.
Also, if the first assumption is correct (just new memory allocations count), what would be the right way to do per-thread object allocations / memory footprint
measurements?
UPD. I tried to check for myself: http://pastebin.com/ECQpz8g4. (sleeps in the code are to allow me to connect to the JVM with JMC).
TL;DR: Allocate a huge int array, then GC it, then allocate some new objects and check allocated memory. Here's what I got:
So, it appears that GC was actually run and, while memory was certainly allocated and subsequently freed, I got this output:
665328 // before everything started
4295684088 // 4 GiB allocated
4295684296 // did GC (for certain! (really?))
5812441672 // allocated a long string, took new memory
So, I'm just waiting for someone with expertise on JVM memory to tell me if I'm right or where am I wrong.