【发布时间】:2016-07-10 15:37:12
【问题描述】:
我想雇用com.sun.management.ThreadMXBean 来做这样的事情:
long before = threadMxBean.getThreadAllocatedBytes(currentThreadId);
seriousBusiness(); // some calls here
long after = threadMxBean.getThreadAllocatedBytes(currentThreadId);
long allocDiff = after - before; // use for stats or whatever
问题是,这个方法实际返回的是什么:方法调用时分配的新内存量或分配对象的大小?要清楚我的意思是什么:
1) 假设我在 seriousBusiness() 调用中分配了一个巨大的数组,因此为此目的分配了一个新的内存区域,getThreadAllocatedBytes 会增加相应的值。
2) 一段时间过去了,有一个 GC 运行,未使用的数组被收集,内存区域现在是空闲的。
3) 我再次调用(在同一个线程中),JVM 发现它不需要分配新内存并为新目的重用该内存区域,这导致getThreadAllocatedBytes 值没有增长。
我可能对 JVM 内存管理的工作方式不太准确,但问题应该很清楚。
另外,如果第一个假设是正确的(仅计算新的内存分配),那么进行per-thread object allocations / memory footprint 测量的正确方法是什么?
UPD。我试着检查自己:http://pastebin.com/ECQpz8g4。 (代码中的sleep是为了让我用JMC连接到JVM)。
TL;DR:分配一个巨大的 int 数组,然后对它进行 GC,然后分配一些新对象并检查分配的内存。这是我得到的:
因此,看起来 GC 实际运行了,虽然内存肯定已分配并随后释放,但我得到了以下输出:
665328 // before everything started
4295684088 // 4 GiB allocated
4295684296 // did GC (for certain! (really?))
5812441672 // allocated a long string, took new memory
所以,我只是在等待具有 JVM 内存专业知识的人告诉我我是对还是错。
【问题讨论】:
标签: java performance memory-management jvm jmx