2010-02-14 32 views
19

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

+9

由于什么原因,您需要知道活堆对象的数量?有机会有更好的方式去做你想做的事。 – 2010-02-14 20:23:49

+1

你想从程序本身获取这些信息吗?或者使用调试工具? – 2017-12-21 04:17:12

回答

5

有一个黑客可以尝试:

  • 创建自己的java.lang.Object中(复制原始源)
  • 在构造函数(不要求阵列)
  • 算创建的对象
  • 将类路径添加到引导类路径

请参阅此(旧)article的示例。

也许有更好的方式使用JPDAJMX做到这一点,但我还没有发现如何...

+3

1)注意:这种破解*可能*会破坏JVM的稳定性。 2)我不认为它会通过反序列化一个序列化的对象流来计算“创建”的对象。 (默认的反序列化绕过对象构造函数。) – 2010-02-15 00:05:41

0

据我所知,你不能。你可以,但是,得到的内存用于程序的数量:

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

如果使用某种Factory类的,你可以找到堆中的对象的数量创建了所有对象。即使那样你也必须在finalize()方法中有一些东西。当然,这不能用于所有物体,例如jdk库类不能被修改。但是,如果你想查找你创建的特定类的实例数量,你可能会发现。

+3

如果我有像String a =“abc”; A = A + “​​DEF”; 你将如何跟踪工厂中的物体数量 – 2010-02-14 20:43:19

0

对于调试,您可以使用一个分析器(如YourKit,一个商业Java分析器)。您会发现java分析器的开源和商业变体。

为了与您的代码集成,您可以使用“面向方面编程”技术。 AOP框架(例如AspectWerkz)允许您在类加载时更改类文件。这将允许您修改构造函数以将对象注册到您的“所有我的运行时对象框架”中。

12

jmap是标准的java工具,您可以使用它来捕获堆转储和统计信息。我不能说jmap使用什么协议连接到JVM以获取此信息,并且不清楚这些信息是否可用于在JVM中直接运行的程序(尽管我确信该程序可以查询它的JVM通过一些套接字来获取这些信息)。 JVM TI是一个由C代码使用的工具接口,它有几乎完全的JVM访问权限,但它是C代码,不能被JVM直接使用。你也许可以编写一个C库,然后与它进行交互,但是没有任何东西可用。

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

如果你想要一些快速(易于实现,不一定是jmap需要一些时间的快速结果),我将分离出一段jmap,然后简单地读取结果文件。

-1
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(); 
    } 
} 
0
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 
    } 
} 
6

使用jvisualvm,并做了内存样品。它会显示类和实例的数量:

enter image description here

+1

为了澄清,jvisualvm是Sun JDK的一部分(所选的截图可能会误导一些人相信它是IntelliJ的一部分)。 – mikewse 2014-06-06 11:23:44

-2
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(); 

    } 

} 
6

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

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

Total 2802946 174459656

第二列是总实例数,而去年是总字节数。