【问题标题】:How to find the number of objects in the heap如何查找堆中的对象数
【发布时间】:2011-01-16 18:49:30
【问题描述】:

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

【问题讨论】:

  • 出于什么原因需要知道活动堆对象的数量?有可能有更好的方法来做你想做的事。
  • 您想从程序本身中获取此信息吗?还是使用调试工具?

标签: java heap-memory


【解决方案1】:

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

JVM TI 是 C 代码使用的工具接口,它几乎可以完全访问 JVM 的运行情况,但它是 C 代码,JVM 不能直接使用。您可能可以编写一个 C lib,然后与它进行交互,但没有什么是开箱即用的。

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

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

【讨论】:

    【解决方案2】:

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

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

    Total 2802946 174459656

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

    【讨论】:

      【解决方案3】:

      使用jvisualvm,并进行内存采样。它将显示类和实例的数量:

      【讨论】:

      • 澄清一下,jvisualvm 是 Sun JDK 的一部分(所选截图可能会误导一些人认为它是 IntelliJ 的一部分)。
      【解决方案4】:

      您可以尝试一个 hack:

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

      请参阅此(旧)article 以获取示例。

      使用JPDAJMX 可能有更好的方法,但我还没有找到如何...

      【讨论】:

      • 1) 当心:这个 hack 可能 破坏你的 JVM。 2)我认为它不会通过反序列化序列化对象流来计算“创建”的对象。 (默认反序列化绕过对象构造函数。)
      【解决方案5】:

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

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

      【讨论】:

        【解决方案6】:

        如果您的所有对象都是使用某种Factory 类创建的,您可以在堆中找到对象的数量。即使那样,您也必须在 finalize() 方法中包含一些内容。当然,这不能对所有对象都进行,例如无法修改 jdk 库类。但是,如果您想查找已创建的特定类的实例数,您可能会找到。

        【讨论】:

        • 如果我有类似 String a = "abc"; a=a+“定义”;您将如何通过您的工厂跟踪对象的数量
        【解决方案7】:

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

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

        【讨论】:

          【解决方案8】:
          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 
              }
          }
          

          【讨论】:

            【解决方案9】:
            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();
              }
            }
            

            【讨论】:

              【解决方案10】:
              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();
              
                  }
              
              }
              

              【讨论】:

                猜你喜欢
                • 2012-09-13
                • 1970-01-01
                • 1970-01-01
                • 2014-08-02
                • 2011-11-24
                • 2010-12-04
                • 2015-12-19
                • 2015-02-12
                • 1970-01-01
                相关资源
                最近更新 更多