跳到正文
返回JVM 与内存

JVM 与内存 整理

JVM 内存区域:先分清规范与实现

堆、栈、元空间,以及为什么 Xmx 不是整个 Java 进程的内存。

先回答:堆设置为 640MB,为什么进程用的内存可能更多?

最大堆内存只是进程内存的一部分。Java 进程还会使用线程栈、类元数据、代码缓存、直接内存和其他本地内存等。Xmx 不能作为整个进程内存占用的硬上限。

运行时数据区先按规范理解

JVM 规范描述了堆、方法区、运行时常量池、虚拟机栈、本地方法栈和程序计数器等概念。堆和方法区由线程共享,栈及程序计数器等与线程执行相关。

规范中的方法区不应直接等同于某个实现版本的“永久代”或“元空间”。HotSpot 在 JDK 8 中以元空间存放类元数据,它使用本地内存,是实现选择的一部分。

栈和堆回答到什么程度

方法调用对应栈帧,涉及局部变量、操作数栈等;对象通常在堆上分配。讨论逃逸分析或标量替换时,要区分语义模型与编译器优化,不能把优化描述成所有对象都必然在栈上分配。

栈深度过大可能出现 StackOverflowError。OutOfMemoryError 可能来自不同内存区域,应先看具体错误信息和运行参数。

小内存服务器上的检查顺序

  • 先看系统可用内存、进程总内存和堆使用情况,不只盯 Xmx。
  • 确认线程数量、元空间、直接内存和连接池等是否有合理边界。
  • 根据现场选择 jcmd、GC 日志、堆转储等手段;转储和诊断也可能占用磁盘或影响服务。
  • 先保留证据,再决定是参数不足、流量变化还是持续泄漏。

延伸阅读

以上为个人整理。涉及版本实现和线上使用时,请结合对应文档与实际测试判断。