【发布时间】:2018-09-18 14:49:33
【问题描述】:
我即将开始使用第 3 方闭源库来加载一堆数据,并想检查它的速度以及加载一个“集”数据需要多少内存。我编写了这个简单的工具来调用数据加载来计时,并使用 YourKit 快速查看内存使用情况并深入研究 CPU 时间。
我在 Windows 7 上运行它,在 JDK8 上使用 Eclipse,没有 VM 参数。
public static void main(String[] args){
long start = System.currentTimeMillis();
// There are a few more calls involved, but not much
BlackBoxDataProvider bd = new BlackBoxDataProvider("c:\\thedata");
BlackBoxData = bd.loadTheData();
System.out.println(System.currentTimeMillis() - start + "ms");
// Keep the application alive so I can have a quick look at memory usage
while(true) {
Thread.sleep(1000);
}
}
这是加载完成后 YourKit 的内存快照:
然后我使用 YourKit 来“强制”垃圾收集,这发生了:
显然这不是现实生活中的场景,因为我被困在 main 方法中,在主线程上,所以我的一些引用不会被清理,但我不知道为什么内存分配会保持增加。
每次我单击“强制系统 GC”时,分配都会增加。在停止增加之前,我达到了 11.9GB。
为什么会这样?
【问题讨论】:
-
据我所见,堆的行为符合预期,即 Eden 空间和 Old Gen 不参与该增长。只有“分配的所有池”在增长……
-
是的,我的问题是为什么“分配的所有池”不断增长。
-
这归结为“分配的所有池”实际上意味着什么的问题,只有 YourKit 可以回答。是 MetaSpace、堆外内存(I/O 缓冲区)还是其他?那么,您是否尝试过使用不同的监控工具(例如 VisualVM 或 FlightRecorder)并比较结果?
-
使用 ProcessExplorer 显示私有字节的增长速度与“分配所有池”的速度相同。该进程继续分配更多内存,大概是为 GC 分配的,我想知道它为什么分配这么多
-
我并不怀疑它在分配字节,但了解 为什么 或用于什么目的会很有帮助。如前所述,此内存不属于普通堆,因此了解实际类别会有所帮助。其他工具,如提到的 VisualVM 或 FlightRecorder 可能会提供更有用的统计信息。此外,尝试使用其他工具有助于验证内存分配不是由 YourKit 本身引起的。您也可以将
while(true) { Thread.sleep(1000); }替换为while(true) { Thread.sleep(1000); System.gc(); },看看应用触发的GC是否有类似的行为。
标签: java garbage-collection yourkit