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

相关推荐
martian6654 小时前
【Java高级篇】——第16篇:高性能Java应用优化与调优
java·开发语言·jvm
李长渊哦11 小时前
Java 虚拟机(JVM)方法区详解
java·开发语言·jvm
二十七剑17 小时前
jvm中各个参数的理解
java·jvm
七禾页话20 小时前
垃圾回收知识点
java·开发语言·jvm
小梁不秃捏2 天前
深入浅出Java虚拟机(JVM)核心原理
java·开发语言·jvm
xiaolingting2 天前
JVM层面的JAVA类和实例(Klass-OOP)
java·jvm·oop·klass·instanceklass·class对象
神仙别闹2 天前
基于Python+Sqlite实现的选课系统
jvm·python·sqlite
上分小子2.02 天前
jvm-Java虚拟机
java·开发语言·jvm
5xidixi2 天前
JAVA EE初阶 JVM
java·jvm·java-ee
北城以南没有天2 天前
排查JVM的一些命令
jvm