Java 如何查找堆中的对象数

Java 如何查找堆中的对象数,java,heap,Java,Heap,如何在Java程序中找到堆上活动对象的数量?据我所知,您不能。但是,您可以获取程序使用的内存量: Runtime rt = Runtime.getRuntime(); System.out.println("Used: " + (rt.totalMemory() - rt.freeMemory()); System.out.println("Free: " + rt.freeMemory()); System.out.println("Total: " + rt.totalMemory(

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

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

 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库类。但是,如果您想找到您创建的特定类的实例数量,您可以找到它。

为了进行调试,您可以使用探查器(如商用java探查器YourKit)。您将发现java分析器的开源和商业变体


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

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

JVMTI是C代码使用的工具接口,它几乎可以完全访问JVM的运行情况,但它是C代码,JVM不能直接使用它。您可能会编写一个C库,然后与之接口,但是没有现成的东西

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


如果您想要快速(易于实现,不一定是一个快速的结果,因为jmap需要一些时间),我会运行一次jmap,然后简单地读取结果文件。

有一种方法您可以尝试:

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

也许有更好的方法使用or来实现,但我还没有找到如何…

公共类NumOfObjects{
静态整数计数=0;
{
计数++;
}
公共静态void main(字符串[]args)
{
NumOfObjects no1=新的NumOfObjects();
System.out.println(“no1:+count);//1
NumOfObjects no2=新的NumOfObjects();
System.out.println(“no2:+count);//2
对于(int i=0;i使用,并执行内存示例。它将显示类和实例的数量:

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

    }

}

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

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

总计2802946 174459656


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

为什么需要知道活动堆对象的数量?可能有更好的方法来实现您的目的。您想从程序本身内部获取此信息吗?还是使用调试工具?如果我有类似字符串a=“abc”;a=a+“def”的内容;您将如何通过工厂跟踪对象的数量1)小心:这种黑客行为可能会破坏JVM的稳定性。2)我认为它不会计算通过反序列化对象流“创建”的对象数。(默认反序列化绕过对象构造函数。)澄清一下,jvisualvm是Sun JDK的一部分(选择的截图可能会误导一些人,使他们相信它是IntelliJ的一部分)。
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 
    }
}
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();

    }

}