jvm 内存结构 ^_^

1. 程序计数器

2. 虚拟机栈

3. 本地方法栈

4. 堆

5. 方法区

程序计数器

定义:

Program Counter Register 程序计数器(寄存器)

作用,是记住下一条jvm指令的执行地址

特点:
是线程私有的
不会存在内存溢出

虚拟机栈

每个线程运行时所需要的内存,称为虚拟机栈

每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存

每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法

线程运行诊断

案例1: cpu 占用过多

定位

用top定位哪个进程对cpu的占用过高

ps H -eo pid,tid,%cpu | grep 进程id (用ps命令进一步定位是哪个线程引起的cpu占用过高)

jstack 进程id

可以根据线程id 找到有问题的线程,进一步定位到问题代码的源码行号

案例2:程序运行很长时间没有结果 (死锁)

本地方法栈

堆

通过 new 关键字,创建对象都会使用堆内存

它是线程共享的,堆中对象都需要考虑线程安全的问题

有垃圾回收机制

堆内存溢出

堆内存诊断

  1. jps 工具
    查看当前系统中有哪些 java 进程
  2. jmap 工具
    查看堆内存占用情况 jmap - heap 进程id
  3. jconsole 工具
    图形界面的,多功能的监测工具,可以连续监测

垃圾回收后,内存占用仍然很高

按照大部分人的理解,FullGC 之后 JVM 进程会释放的内存一部分还给物理内存,

1.在 JDK8 + CMS 的配置下,JVM 并不是立马归还内存给到操作系统,而是随着 FullGC 次数的增多逐渐归还,最终会全部归还

2.在 JDK8 + G1 的配置下,JVM 都是在每一次 FullGC 后全部归还物理内存。

如果代码保持不变,但是JVM参数中设置Xms和Xmx相同的话,不管是否有FullGC,堆内存大小都不发生变化,也就不释放内存给操作系统

GC 后如何归还内存给操作系统:

能不能归还,主要依赖于 Xms 和 Xmx 是否相等

何时归还,主要依赖于 JDK 版本和垃圾回收器类型

只有 FullGC 的时候才能真正触发堆内存收缩归还 OS。YGC 是不能使 JVM 主动归还内存给操作系统的。

尽量保持 Xms 和 Xmx 一致,这样可以减少堆内存调整带来的性能损耗,也可以减少堆内存调整带来的无内存风险。

参考:

https://segmentfault.com/a/1190000019856974

https://www.cnblogs.com/androidsuperman/p/11743103.html

http://blog.dutycode.com

方法区

定义

1.8 以前会导致永久代内存溢出

bash 复制代码
* 演示永久代内存溢出 java.lang.OutOfMemoryError: PermGen space
* -XX:MaxPermSize=8m

1.8 之后会导致元空间内存溢出

bash 复制代码
* 演示元空间内存溢出 java.lang.OutOfMemoryError: Metaspace
* -XX:MaxMetaspaceSize=8m

运行时常量池

常量池,就是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量

等信息

运行时常量池,常量池是 *.class 文件中的,当该类被加载,它的常量池信息就会放入运行时常量

池,并把里面的符号地址变为真实地址

StringTable

相关推荐
明天也要努力学习21 小时前
深入理解 JVM 垃圾回收(GC)
java·jvm
铁链鞭策大师21 小时前
jvm基础
jvm
香蕉大香蕉(06敬畏市场)2 天前
高频八股 · JVM(8)
java·jvm·面试·八股·大厂实习
北冥you鱼2 天前
Go 语言 GORM 使用 Preload:从关联查询到嵌套预加载的完整实践
开发语言·jvm·golang
兔头?2 天前
JVM学习文档
jvm·学习
wuminyu2 天前
JVM规范学习总结:class执行性能差异
java·linux·c语言·jvm·c++
EVEN-09132 天前
Linux-线程控制
linux·jvm
刚入门的大一新生3 天前
Linux-线程概念
linux·jvm
eleven_4u3 天前
QPS如何计算,如何部署架构
java·linux·运维·jvm·中间件
qq_452396233 天前
第八篇:《VACUUM、自动清理与膨胀治理》
jvm·数据库·oracle