JVM(类加载机制/运行时数据区/JIT)
2020-10-13 16:35:28 0 举报
AI智能生成
JVM虚拟机
作者其他创作
大纲/内容
Java内存模型
JMM
JMM是一套规范,规定了所有的变量都存储在主内存中,每个线程还有自己的工作内存
线程的工作内存中保存了该线程使用到主内存中的变量拷贝,线程对变量的所有操作都
必须在工作内存中进行,而不能直接读写主内存中的变量
必须在工作内存中进行,而不能直接读写主内存中的变量
不同线程之间无法直接访问对方工作内存中的变量,线程间的通信均需要在主内存完成
线程安全的特性
原子性
可见性
有序性
类加载机制
(按需加载)
(按需加载)
加载过程
生命周期
生命周期
加载:将二进制class文件加载到内存
验证:确保类加载的正确性(文件格式、元数据、字节码、符号引用等)
准备:为静态变量分配内存,默认值
解析:把符号引用转化为直接引用
初始化:为静态变量赋初始值
使用、卸载
类加载器
种类
启动类加载器:Bootstrap Classloader
加载 JAVA_HOME/jre/lib 下的文件
扩展类加载器:Extension ClassLoader
加载 JAVA_HOME/jre/lib/ext 下的文件
应用程序类加载器:Application ClassLoader
也叫系统类加载器:System ClassLoader
也叫系统类加载器:System ClassLoader
工作中接触最多的类加载器
加载 classpath 下的文件
加载 classpath 下的文件
自定义类加载器:必须继承 ClassLoader
作用
将类的字节码文件从JVM外部加载到内存中
确定一个类的唯一性
提供隔离特性,为中间件开发者提供便利(例如Tomcat)
双亲委派机制
优先委托父类加载,父类不能加载时才自己加载
作用:不重复加载,安全,防止系统类被修改
运行时数据区
方法区(理论)
永久代/元空间
永久代/元空间
线程共享,用于存储已被虚拟机加载的类信息、常
量、静态变量、即时编译器编译后的代码等数据
量、静态变量、即时编译器编译后的代码等数据
永久代和元空间的区别?
jdk1.7以前叫永久代,jdk1.8开始叫元空间
永久代是存放在堆区的,元空间存在于直接内存(操作系统内存)
元空间的调优
最小、最大元空间设置成一样大
大小设置为物理内存的 1/32
预留20%-30%的空间
堆
存放对象实例,所有线程共享
GC的主要工作场所
栈
线程私有,描述的是 Java 方法执行的内存模型
每个方法被执行的时候都会创建一个栈帧用于存储
局部变量表、操作栈、动态链接、方法出口等信息
局部变量表、操作栈、动态链接、方法出口等信息
每一个方法被调用直至执行完成的过程,就对应
着一个栈帧在虚拟机栈中从入栈到出栈的过程
着一个栈帧在虚拟机栈中从入栈到出栈的过程
本地方法栈
本地方法栈与虚拟机栈类似,只不过虚拟机栈是为
Java方法提供服务,本地方法栈是为native方法服务
Java方法提供服务,本地方法栈是为native方法服务
程序计数器
线程私有,实现流程控制和记录执行位置
如果当前正在执行的是本地方法则程序计数器为空
JVM调优
栈内存溢出
StackOverflowError
StackOverflowError
原因:栈的内存大小不允许动态扩展,当线程请求栈的深度超过当前Java虚拟机栈的最大深度
解决:检测是否有死循环,修复代码 bug
堆内存溢出
OutOfMemory
OutOfMemory
原因:堆内存被用光,或者内存泄漏堆积导致
OOM
对象太多(Java heap space)
使用 -Xmx 增加堆内存大小,修复内存泄露
GC回收超时(GC overhead limit exceeded)
使用 -XX:-UseGCOverheadLimit 取消 GC 开销限制
本地内存不足(Direct buffer memory)
打印的堆栈跟踪信息,使用操作系统本地工具进行诊断
线程太多(unable to create new native thread)
减少堆内存或线程栈的大小来达到创建更多线程的目的
元空间内存不足(Metaspace)
使用-XX: MaxMetaSpaceSize 增加 metaspace 大小
内存泄漏
原因:程序在申请内存后,无法释放已申请的内存空间
内存泄露排查
检测是否频繁发生Full GC
使用 jps -l 获取 pid
使用 jstack -gcutil pid 1000
每1000毫秒查询一次
gcutil:已使用空间占总空间的百分比
使用 jmap 生成堆转储快照文件 jmap -histo:live pid
通过MAT查看Histogram图即可找出是哪块代码
线程死锁
四个必要条件
互斥、请求和保持、不可剥夺、环路等待
预防死锁
破坏四个必要条件中任意一个都可以
指定加锁顺序、设置超时时间
银行家算法
保证系统动态分配资源后不进入不安全状态
死锁检测工具
Jstack和Jconsole
调优工具
JDK自带Jstat、Jinfo、Jmap、Jhat、Jstack
JvisualVM、Jconsole
阿里巴巴JVM调优工具:ArtThas
GC日志分析工具
GCEasy
GCViewer
故障定位
系统CPU占用过高
先用top命令找到CPU占比最高的应用进程
ps -ef | grep ** 或 jps -l 获得进程编号 pid
ps -mp pid -o THREAD,tid,time 获取线程编号
或者使用 top -Hp pid(H:显示线程信息)
或者使用 top -Hp pid(H:显示线程信息)
将获取到的线程ID转换为16进制格式(英文小写)
最后使用 jstack pid | grep tid -A60
0 条评论
下一页