java - 如何在java中的堆上单独获取所有对象消耗的运行时内存

Posted

技术标签:

【中文标题】java - 如何在java中的堆上单独获取所有对象消耗的运行时内存【英文标题】:How to get runtime memory consumed by all the objects individually on heap in java 【发布时间】:2013-08-16 07:16:44 【问题描述】:

我目前正在运行以下代码,这表明我的 java 应用程序正在使用近 5mb 的内存。但是我的 mac 的活动监视器说它使用 185 mb。额外的内存在哪里使用?即使我的应用处于空闲状态,我消耗的内存也在不断增加,从 5 mb 上升到 7 mb。

还有任何 java 类可以让我观察堆上的最新对象(所有对象分别)以及运行时的内存消耗吗?

  package profiling;

    public class MemConsumption 


        public static void profiling() 
            Runtime runtime = Runtime.getRuntime();
            long memory = runtime.totalMemory() - runtime.freeMemory();
            System.out.println("Used memory is bytes: " + memory);
            System.out.println("Used memory is megabytes: "
                    + bytesToMegabytes(memory));

        

        public static long bytesToMegabytes(long bytes) 
                final long MEGABYTE = 1024L * 1024L;//1024 kb of 1024 bytes

            return bytes / MEGABYTE;
        

    

【问题讨论】:

【参考方案1】:

我目前正在运行以下代码,这表明我的 java 应用程序正在使用近 5mb 的内存。

这是分配的 hep 数量,对象实际使用的数量可能会更小。

如果您想要更准确的记帐,您可以使用-XX:-UseTLAB,您将看到使用了多少字节。注意:多线程应用程序的速度要慢得多,但要准确得多。

但我的 Mac 的活动监视器显示它使用 185 mb。额外的内存在哪里使用?

很可能它会显示您正在使用多少虚拟内存,其中包括最大堆大小(堆的地址空间在启动时保留)和共享库、线程堆栈、perm gen ,直接内存,内存映射文件,例如字节缓冲区等

注意:虚拟内存不代表分配的内存量,并且是进程独有的。

即使我的应用处于空闲状态,我消耗的内存也在不断增加,从 5 mb 上升到 7 mb。

如果您没有真正做任何事情,您是如何确定堆大小的?监控应用程序使用一些堆。

还有任何 java 类可以让我观察堆上的最新对象(所有对象分别)以及运行时的内存消耗吗?

您需要转储堆并在 VisualVM 或商业分析器中查看它。

BTW MB = 兆字节,Mb = 兆位,mb = 毫位

【讨论】:

也许你还提到了直接内存使用 我只是打印使用的内存,检查行 - System.out.println("Used memory is bytes: " + memory); ,那为什么我的内存消耗越来越大? 当我尝试转储数据时,visualvm 说“无法在我的应用程序上堆转储”为什么?

以上是关于java - 如何在java中的堆上单独获取所有对象消耗的运行时内存的主要内容,如果未能解决你的问题,请参考以下文章

Java中的堆内存设置对线程创建数的影响以及-Xss参数的记录

Java中对象都是分配在堆上吗?你错了!

在C中的堆上分配数组

两个或多个线程如何在它们分配的堆上共享内存?

JVM-堆

jvmiz9是什么意思