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

时间:2013-08-16 07:16:45

标签: java memory profiling

我目前正在运行以下代码,这表明我的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 个答案:

答案 0 :(得分:4)

  

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

这是分配的肝脏量,对象使用的实际量可能更小。

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

  

但我的mac的活动监视器说它使用185 MB。使用的额外内存在哪里?

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

注意:虚拟内存不代表已分配的内存量,也不代表进程的唯一内存。

  

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

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

  

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

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

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