如何查看应用程序当前所使用的堆大小?

84

我认为我在NetBeans中将堆大小增加到了1 GB,因为我将配置更改为以下内容:

netbeans_default_options="-J-Xmx1g ......

我重新启动了NetBeans,那么我可以确定我的应用程序现在被分配了1 GB吗?

有什么方法可以验证这一点吗?

7个回答

232

使用此代码:

// Get current size of heap in bytes
long heapSize = Runtime.getRuntime().totalMemory(); 

// Get maximum size of heap in bytes. The heap cannot grow beyond this size.// Any attempt will result in an OutOfMemoryException.
long heapMaxSize = Runtime.getRuntime().maxMemory();

 // Get amount of free memory within the heap in bytes. This size will increase // after garbage collection and decrease as new objects are created.
long heapFreeSize = Runtime.getRuntime().freeMemory(); 

知道这对我很有用。


如果你使用这种策略,你需要重新编译你的应用程序(NetBeans)。 - vkraemer
5
根据文档:https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#freeMemory()。上述方法返回的是JVM中的内存,不一定是堆内存。 - balboa_21
请注意,您使用“-J-Xmx 1g”指定的堆大小并非全部可用于应用程序对象。虚拟机,特别是垃圾回收器,可能会使用其中的一些内存。有关此主题的更多信息,请参见此处 - Matthias Braun

23
public class CheckHeapSize {

    public static void main(String[] args) {
        long heapSize = Runtime.getRuntime().totalMemory(); 

        // Get maximum size of heap in bytes. The heap cannot grow beyond this size.// Any attempt will result in an OutOfMemoryException.
        long heapMaxSize = Runtime.getRuntime().maxMemory();

         // Get amount of free memory within the heap in bytes. This size will increase // after garbage collection and decrease as new objects are created.
        long heapFreeSize = Runtime.getRuntime().freeMemory(); 
        
        System.out.println("heap size: " + formatSize(heapSize));
        System.out.println("heap max size: " + formatSize(heapMaxSize));
        System.out.println("heap free size: " + formatSize(heapFreeSize));
        
    }
    public static String formatSize(long v) {
        if (v < 1024) return v + " B";
        int z = (63 - Long.numberOfLeadingZeros(v)) / 10;
        return String.format("%.1f %sB", (double)v / (1L << (z*10)), " KMGTPE".charAt(z));
    }
}

2
使用以下代码以人类可读的格式获取内存的HeapSize - ram kumar
1
1千字节(1 KB)= 1000字节。1 kibibyte(1 KiB)= 1024字节。 - bcody

16

你可以通过 MXBeans 来实现

public class Check {
    public static void main(String[] args) {
        MemoryMXBean memBean = ManagementFactory.getMemoryMXBean() ;
        MemoryUsage heapMemoryUsage = memBean.getHeapMemoryUsage();

        System.out.println(heapMemoryUsage.getMax()); // max memory allowed for jvm -Xmx flag (-1 if isn't specified)
        System.out.println(heapMemoryUsage.getCommitted()); // given memory to JVM by OS ( may fail to reach getMax, if there isn't more memory)
        System.out.println(heapMemoryUsage.getUsed()); // used now by your heap
        System.out.println(heapMemoryUsage.getInit()); // -Xms flag

        // |------------------ max ------------------------| allowed to be occupied by you from OS (less than xmX due to empty survival space)
        // |------------------ committed -------|          | now taken from OS
        // |------------------ used --|                    | used by your heap

    }
}

但请记住,它等同于Runtime.getRuntime()(从这里获取的示意图)
memoryMxBean.getHeapMemoryUsage().getUsed()      <=> runtime.totalMemory() - runtime.freeMemory()
memoryMxBean.getHeapMemoryUsage().getCommitted() <=> runtime.totalMemory()
memoryMxBean.getHeapMemoryUsage().getMax()       <=> runtime.maxMemory()

来自javaDoc

init - 表示Java虚拟机在启动时从操作系统请求用于内存管理的初始内存量(以字节为单位)。 Java虚拟机可能会从操作系统请求额外的内存,并随着时间的推移释放内存。 init的值可能未定义。

used - 表示当前使用的内存量(以字节为单位)。

committed - 表示保证供Java虚拟机使用的内存量(以字节为单位)。 承诺的内存量可能随时间而变化(增加或减少)。 Java虚拟机可以将内存释放给系统,因此committed可能小于init。 committed始终大于或等于used。

max - 表示可用于内存管理的最大内存量(以字节为单位)。 它的值可能未定义。 如果已定义,则最大内存量可能随时间而变化。 如果已定义,则使用和承诺的内存量始终小于或等于max。即使在used <= max仍为真的情况下(例如,当系统低于虚拟内存时),如果尝试增加已使用的内存量使得used > committed,则内存分配也可能失败。

    +----------------------------------------------+
    +////////////////           |                  +
    +////////////////           |                  +
    +----------------------------------------------+

    |--------|
       init
    |---------------|
           used
    |---------------------------|
              committed
    |----------------------------------------------|
                        max

作为附加说明,maxMemory比-Xmx小是因为至少需要一个空的survival space,这个空间不能用于堆分配。
另外,值得一看的是这里,特别是这里

9
你可以使用jconsole(大多数JDK都标配)来检查任何Java进程的堆大小。

这包括内存使用、线程和类的实时图表。非常有用。 - vkraemer

3

如果 jvisualvm 太过复杂或者你只需使用命令行,我个人推荐使用 jvmtop

JvmTop 0.8.0 alpha   amd64  8 cpus, Linux 2.6.32-27, load avg 0.12
https://github.com/patric-r/jvmtop

PID MAIN-CLASS      HPCUR HPMAX NHCUR NHMAX    CPU     GC    VM USERNAME   #T DL
3370 rapperSimpleApp  165m  455m  109m  176m  0.12%  0.00% S6U37 web        21
11272 ver.resin.Resin [ERROR: Could not attach to VM]
27338 WatchdogManager   11m   28m   23m  130m  0.00%  0.00% S6U37 web        31
19187 m.jvmtop.JvmTop   20m 3544m   13m  130m  0.93%  0.47% S6U37 web        20
16733 artup.Bootstrap  159m  455m  166m  304m  0.12%  0.00% S6U37 web        46

2

使用Sun Java 6 JDK的jvisualvm进行附加。列出了启动标志。


2
二进制文件名为jvisualvm(.exe)。不知道为什么。 - Thorbjørn Ravn Andersen

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接