如何查找堆中的对象数

如何在Java程序中找到堆上活动对象的数量?

有一个黑客,你可以尝试:

  • 创建自己的java.lang.Object(复制原始源代码)
  • 计算构造函数中创建的对象(不为数组调用)
  • 将类文件的路径添加到引导类路径

请参阅此(旧) 文章以获取样本。

可能有更好的方法使用JPDA或JMX ,但我没有找到…

jmap是标准的java实用程序,可用于捕获堆转储和统计信息。 我不能说jmap使用什么协议连接到JVM来获取这些信息,并且不清楚这些信息是否可以直接在JVM中运行的程序(虽然我确信程序可以查询它的JVM)通过一些套接字来获取此信息)。

JVM TI是C代码使用的工具接口,它几乎可以完全访问JVM,但它是C代码,而不是JVM直接提供的。 您可以编写一个C lib然后与它进行交互,但没有任何开箱即用的function。

有几个JMX MBean,但我不认为它们中的任何一个提供实际的对象计数。 您可以从这些获取内存统计信息(这些是JConsole使用的)。 查看java.lang.management类。

如果你想要一些快速(易于实现,不一定是一个快速的结果,因为jmap需要一些时间),我会分叉一段jmap,并只是读取生成的文件。

最简单的方法是使用jmap工具。 如果您将在最后打印对象直方图,您将看到实例的总数以及所有对象的累积大小:

jmap -histo 将打印具有实例数和大小的整个对象。 最后一行将包含总数

Total 2802946 174459656

第二列是总实例计数,最后一列是总字节数。

使用jvisualvm ,并做一个内存示例。 它将显示类和实例的数量:

在此处输入图像描述

据我所知,你不能。 但是,您可以获得该程序使用的内存量:

  Runtime rt = Runtime.getRuntime(); System.out.println("Used: " + (rt.totalMemory() - rt.freeMemory()); System.out.println("Free: " + rt.freeMemory()); System.out.println("Total: " + rt.totalMemory()); 

如果使用某种Factory类创建所有对象,则可以在堆中找到多个对象。 即便如此,你还必须在finalize()方法中拥有一些东西。 当然,这不能对所有对象进行,例如,jdk库类不能被修改。 但是,如果要查找已创建的特定类的实例数,则可以找到该实例。

对于调试,您可以使用分析器(如YourKit,商业Java分析器)。 您将找到java profilers的开源和商业变体。

为了与代码集成,您可以考虑使用“面向方面编程”技术。 AOP框架(例如AspectWerkz)允许您在类加载时更改类文件。 这将允许您修改构造函数以将对象注册到“all-my-runtime-objects-framework”。

 public class NumOfObjects { static int count=0; { count++; } public static void main(String[] args) { NumOfObjects no1=new NumOfObjects(); System.out.println("no1:" + count);//1 NumOfObjects no2=new NumOfObjects(); System.out.println("no2:"+ count); //2 for (int i=0; i<10;i++) { NumOfObjects noi=new NumOfObjects(); } System.out.println("Total objects:"+count);// 12 } } 
 public class ObjectCount { static int i; ObjectCount() { System.out.println(++i); } public static void main(String args[]) { ObjectCount oc = new ObjectCount(); ObjectCount od = new ObjectCount(); ObjectCount oe = new ObjectCount(); ObjectCount of = new ObjectCount(); ObjectCount og = new ObjectCount(); } } 
 class Test1 { static int count=0; public Test1() { count++; System.out.println("Total Objects"+" "+count); } } public class CountTotalNumberOfObjects { public static void main(String[] args) { Test1 t = new Test1(); Test1 t1 = new Test1(); Test1 t3 = new Test1(); Test1 t11 = new Test1(); Test1 t111 = new Test1(); Test1 t13 = new Test1(); } }