JVM
2022-10-26 07:46:14 0 举报
AI智能生成
jvm之实现
作者其他创作
大纲/内容
java 如何从源代码转换成机器码执行的
线程私有:程序计数器、虚拟机栈、本地方法栈
哪些是线程私有的,哪些是线程共享的
程序计数器
虚拟机栈
栈中存储什么?
本地方法区
通过本地方法,我们可以实现用 Java 与实现了 jre 的底层系统交互, JVM 的一些部分就是 C 语言写的。
有时 Java 应用需要与 Java 外面的环境交互,这就是本地方法存在的原因。
为什么要使用本地方法
在 JDK 7 版本及 JDK 7 版本之前,堆内存被通常分为下面三部分:1. 新生代内存(Young Generation)2. 老生代(Old Generation)3. 永久代(Permanent Generation)
JDK 8 版本之后 PermGen(永久) 已被 Metaspace(元空间) 取代,元空间使用的是直接内存
外框
堆
Direct Memory- 常见于 NIO 操作时,用于数据缓冲区- 分配回收成本较高,但读写性能高- 不受 JVM 内存回收管理
直接内存是操作系统和 Java 代码都可以访问的一块区域,无需将代码从系统内存复制到 Java 堆内存,从而提高了效率。
Java直接内存?
运行时常量池(Runtime Constant Pool)是方法区的一部分。Class 文件中除了有类的版本/字段/方法/接口等描述信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容将类在加载后进入方法区的运行时常量池中存放。
方法区
堆外内存
字符串常量池在JVM哪个位置
String 类和常量池?
谈谈JVM中的常量池?
对象的访问定位的两种方式(句柄和直接指针两种方式)?
除了程序计数器,其他内存区域都有 OOM 的风险。栈一般经常会发生 StackOverflowError,比如 32 位的 windows 系统单进程限制 2G 内存,无限创建线程就会发生栈的 OOM
同时 jstat 查看监控 JVM 的内存和 GC 情况,先观察问题大概出在什么区域;使用 MAT 工具载入到 dump 文件,分析大对象的占用情况,比如 HashMap 做缓存未清理,时间长了就会内存溢出,可以把改为弱引用 。
谈谈对OOM的认识?如何排查OOM的问题?
类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。
永久代会为 GC 带来不必要的复杂度,并且回收效率偏低
元空间的特点:每个加载器有专门的存储空间。不会单独回收某个类。元空间里的对象的位置是固定的。如果发现某个加载器不再存货了,会把相关的空间整个回收
JVM8 为什么要增加元空间,带来什么好处
超链接
内存结构
为什么要有survivor区
为什么要有两个survivor
动态对象年龄的判断
HotSpot VM里GC的种类
对象创建和内存分配策略
如何判断一个对象是否存活?
强引用、软引用、弱引用、虚引用
被引用的对象就一定能存活吗?
GC root有哪些 ?
实例变量可以是GC root 吗 ?
如何判断一个类是无用的类
空间分配担保原则?
如何判断一个常量是废弃常量
垃圾标记
将垃圾标记,然后清除,不需要移动对象,但产生内存碎片
标记-清除算法
将不被GC Root引用的对象回收,清除其占用的内存空间。然后整理剩余的对象,可以有效避免因内存碎片而导致的问题
标记-整理算法
先将被GC Root引用的对象从FROM放入TO中,再回收不被GC Root引用的对象。然后交换FROM和TO。这样也可以避免内存碎片的问题,但是会占用双倍的内存空间。
复制算法
对比
垃圾回收算法
不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率
年轻代,区域相对老年代较小,对象生命周期短、存活率低,回收频繁
老年代,对象生命周期长,存活率高,回收不频繁
分代垃圾回收
① 新创建的对象都被放在 新生代的伊甸园 中
② 当伊甸园空间不足时,会采用 复制算法 进行垃圾回收,这时的回收叫做 ==Minor GC== ;把 伊甸园和幸存区From 存活的对象先复制到幸存区To中,此时 存活的对象寿命+1 ,并清理掉未存活的对象,最后再交换幸存区From和幸存区To;
③ 再次创建对象,若新生代的伊甸园又满了,则同上;
⑤ 如果老年代中的内存都满了,就会先触发Minor GC 如果内存还是不足,则会触发 Full GC ,扫描 新生代和老年代中 所有不再使用的对象并回收、
分代垃圾回收流程
当遇到一个 较大的对象 时,就算新生代的 伊甸园 为空,也 无法容纳该对象 时,会将该对象 直接晋升为老年代
大对象处理策略
当一个线程**抛出OOM异常后**,**它所占据的内存资源会全部被释放掉**,从而不会影响其他线程的运行,**进程依然正常进行**
某个线程的内存溢出了而抛异常(out of memory),会不会让其他的线程结束运行?
JVM中一次完整的GC是什么样子的?
Minor Gc 和 Full GC 有什么不同呢?
触发新生代GC,如果存活对象总量大于survivor区容量,咋办 ?
GC
GC Cause、日志分析
并行收集:指多条垃圾收集线程并行工作,但此时用户线程仍处于等待状态。
并发收集:指用户线程与垃圾收集线程同时工作(不一定是并行的可能会交替执行)。用户程序在继续运行,而垃圾收集程序运行在另一个 CPU 上
吞吐量:即 CPU 用于运行用户代码的时间与 CPU 总消耗时间的比值(吞吐量 = 运行用户代码时间 / ( 运行用户代码时间 + 垃圾收集时间 )),也就是。例如:虚拟机共运行 100 分钟,垃圾收集器花掉 1 分钟,那么吞吐量就是 99% 。
相关概念
串行回收器。Serial、Serial old
并行回收器。ParNew、Parallel Scavenge、Parallel old
并发回收器。CMS、G1
垃圾回收器种类
Young Collection:对新生代垃圾收集,产生stw
Mixed Collection:混合收集中,最终标记会stw,拷贝存活会stw
G1什么时候会stop the world
Young Collection:对新生代垃圾收集
Young Collection + Concurrent Mark:如果老年代内存到达一定的阈值了,新生代垃圾收集同时会执行一些并发的标记。
Mixed Collection:会对新生代 + 老年代 + 幸存区等进行混合收集,然后收集结束,会重新进入新生代收集。
垃圾回收阶段
G1
一种以获取最短回收停顿时间为目标的老年代收集器
详细说一下CMS的回收过程?CMS的问题是什么?
主要优点:并发收集、低停顿。但是它有下面三个明显的缺点:1、对 CPU 资源敏感;2、无法处理浮动垃圾;3、它使用的回收算法-“标记-清除”算法会导致收集结束时会有大量空间碎片产生。
CMS(Concurrent Mark Sweep)
有哪几种垃圾回收器,各自的优缺点是什么?
垃圾回收器
什么是类加载?
加载 -- 连接(验证、准备、解析)---
类加载的过程?
内存中实际上创建了两块内容1 一块内容就是二进制的文件被加载到内存中2 与此同时,生成了 class 类的对象,单例,帮我们解析好,这个对象指向了这块内容,以后就是通过我们自己写的对象访问这个class类的对象,再访问到我们内存的class文件class的对象,在方法区,我们自己写的实例化对象,在堆中
一个class 文件,平时被存在磁盘上,这些内容被load到内存,发生了什么?
Bootstrap ClassLoader(启动类加载器)
Extension ClassLoader(拓展类加载器)
Application ClassLoader(应用程序类加载器)
自定义类加载器
什么是类加载器,常见的类加载器有哪些?
类加载器比较
什么是双亲委派模型?
双亲委派过程?
为什么需要双亲委派模型?
那怎么打破双亲委派模型?
逃逸分析
分支主题
tomcat
类加载
什么场景下需要自定类加载器
如何自定义类加载器
垃圾回收器选型
垃圾回收
对于Full GC次数过多,主要有以下两种原因:代码中一次获取了大量的对象,导致内存溢出,此时可以通过eclipse的mat工具查看内存中有哪些对象比较多;内存占用不高,但是Full GC次数还是比较多,此时可能是显示的System.gc()调用导致GC次数过多,这可以通过添加-XX:+DisableExplicitGC来禁用JVM对显示GC的响应。
系统频繁Full GC导致系统卡顿是怎么回事
案例
频繁GC问题怎么排查
Full GC
哪些地方会出现OOM
内存泄漏
死锁问题
CPU或者内存使用率过高怎么办?
JVM运行情况预估
实战
查看其进程id
Jps
查看内存信息,实例个数以及占用内存大小
jmap -heap pid
查看某个进程的堆信息
堆内存快照
JMAP
导入dump文件进行分析
jvisualvm
jstack 线程id
查看线程情况
jstack
jinfo -sysprops pid
查看正在运行的Java应用程序的扩展参数
Jinfo
jstat -gc pid
垃圾回收统计
jstat -gacapactity pid
堆内存统计
jstat -gcnew pid
新生代回收
其他
查看堆内存各部分的使用量,以及加载类的数量
Jstat
查看整个进程的运行情况,线程、内存、GC、运行环境信息
dashboard
输入 thread -b 可以查看线程死锁
输入 thread加上线程ID 可以查看线程堆栈
输入thread可以查看线程详细情况
Arthas
常用工具
JVM
0 条评论
回复 删除
下一页