我有三个对象:
ClassA classA = new ClassA();
ClassA classB = new ClassA();
ClassA classC = new ClassA();
这些对象中的每一个都有一个名为public void
的{{1}},它会执行某些操作并按以下方式调用:
run
在每次循环迭代中,每个 classA.run();
classB.run();
classC.run();
调用都会生成特定数量的垃圾。
如何准确确定每个run
生成的垃圾量?
答案 0 :(得分:3)
通常(如果你可以说OP的用例),你使用profilers / logging来估算分配压力。例如,JRockit Mission Control(适用于JDK 7u40!)可以转储当前的分配率。持续执行run
,可能会得到估算每run
次呼叫的分配率。确保严格衡量run
通话费率,因为此时您正在处理基准测试。以jmh为例。
run()
,然后获取另一个地址标记,减去两个标记,并在通话期间获得TLAB中浪费的空间量。
事实上,在jol
中,我们有the funny example doing almost exactly this thing。
答案 1 :(得分:2)
有一点知道JVM选项-Xaprof,它报告每个类的全局分配总数。我们创建了一个内部开源“aprof”工具,用于报告每个类别的每种方法的分配率:https://code.devexperts.com/display/AProf/
它通过执行动态字节码修改来执行对象分配跟踪,并尝试平衡性能影响与报告的深度和精度。它确实显着增加了应用程序启动时间,但对运行时性能的影响可以忽略不计,因此我们可以在服务器端组件的生产中使用它。
Aprof精确地收集代码中的所有“新”操作,但不收集每个分配的完整堆栈跟踪。它跟踪每个分配操作的“位置”(类名和方法名),同时提供一种方法将char []的分配(例如,StringBuilder方法)归因于已调用相应StringBuilder方法的实际应用程序代码。它为所有流行的java.lang和java.util类提供了一组合理的默认值,它们在它们内部分配内存,这样你就可以看到你的实际应用程序类作为这些分配的最终位置源。
答案 2 :(得分:0)
您可以尝试使用内置的探查器VisualVM
来查看细节。
您可以在名称jvisualvm.exe
之类的JDK / bin文件夹中找到它。或者类似的东西。
答案 3 :(得分:0)
double[] heapFreeSizez = new double[5];
for(int i = 0 ; i < 5 ; ++i) {
heapFreeSizez[i] = 0;
}
heapFreeSizez[0] = (double) Runtime.getRuntime().freeMemory()/1000000.0;
classA.run(); heapFreeSizez[1] = (double) Runtime.getRuntime().freeMemory()/1000000.0;
classB.run(); heapFreeSizez[2] = (double) Runtime.getRuntime().freeMemory()/1000000.0;
classC.run(); heapFreeSizez[3] = (double) Runtime.getRuntime().freeMemory()/1000000.0;
classD.run(); heapFreeSizez[4] = (double) Runtime.getRuntime().freeMemory()/1000000.0;
for(int i = 1 ; i < 5 ; ++i) {
if(heapFreeSizez[i] - heapFreeSizez[i-1] < 0) {
System.out.println(i + "_" + "HELP!");
}
}
答案 4 :(得分:0)
您可以使用ThreadMXBean#getThreadAllocatedBytes吗?
它告诉您特定线程分配的内存量。
您需要做的只是衡量差异(并考虑getThreadAllocatedBytes
本身产生的大约8-16字节垃圾)