You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Runtime类获取JVM运行时内存的三类技术疑问

JVM内存配置与运行分析

IDEA VM参数

-Xmx100m -Xms100m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags

测试代码

public static void main(String[] args) {
    Runtime rt = Runtime.getRuntime();
    System.out.println(rt.maxMemory());
    System.out.println(rt.totalMemory());
    System.out.println(rt.freeMemory());
}

运行输出

-XX:InitialHeapSize=104857600 -XX:MaxHeapSize=104857600 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
objc[73147]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/bin/java (0x108b194c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x108c5e4e0). One of the two will be used. Which one is undefined.
100663296
100663296
98035184
Heap
 PSYoungGen      total 29696K, used 3078K [0x00000007bdf00000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 25600K, 12% used [0x00000007bdf00000,0x00000007be201b88,0x00000007bf800000)
  from space 4096K, 0% used [0x00000007bfc00000,0x00000007bfc00000,0x00000007c0000000)
  to   space 4096K, 0% used [0x00000007bf800000,0x00000007bf800000,0x00000007bfc00000)
 ParOldGen       total 68608K, used 0K [0x00000007b9c00000, 0x00000007bdf00000, 0x00000007bdf00000)
  object space 68608K, 0% used [0x00000007b9c00000,0x00000007b9c00000,0x00000007bdf00000)
 Metaspace       used 3269K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 359K, capacity 388K, committed 512K, reserved 1048576K

技术问题解答

1. 为什么maxMemory输出值小于配置的100MB?各内存指标含义是什么?

100MB换算字节是104857600,但输出的maxMemory是100663296字节,差异来自JVM会预留一小部分堆内存用于内部管理(比如GC标记、内存结构维护),这部分不会开放给应用程序使用。

三个指标的具体含义:

  • maxMemory():应用程序能用到的最大堆内存,等于-Xmx配置的上限减去JVM内部预留的管理空间。
  • totalMemory():JVM当前已分配的堆内存总量,启动时等于-Xms的初始值,运行中会根据需求动态调整,但不会超过maxMemory。
  • freeMemory():当前堆内存中未被使用的空间,等于totalMemory减去已使用的堆内存。

2. 为什么输出里Metaspace看起来属于Heap区域?

这只是日志排版的问题,Metaspace完全不属于堆内存。它是JDK8及以后在本地内存(Native Memory)中开辟的区域,专门存储类元数据、常量池等信息,用来替代之前的永久代。日志把它放在Heap区块下方打印,只是格式习惯,实际和堆内存是完全独立的。

3. PSYoungGen与ParOldGen的总和不等于100MB配置,原因是什么?

计算两者总和:29696K + 68608K = 98304K(约96MB),确实小于100MB。原因有两点:
一是年轻代除了Eden和Survivor区,JVM会预留一部分内存作为GC分配担保空间,用于老年代内存不足时的临时周转;
二是-Xmx配置的是整个堆的总上限,包含年轻代、老年代,以及JVM为堆内存分配的内部管理结构空间,这些额外空间不会被统计到YoungGen和OldGen的total值里,所以两者总和会略小于配置的堆内存上限。

内容的提问来源于stack exchange,提问作者Jack Ma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 11:10:37