0
点赞
收藏
分享

微信扫一扫

JVM整理

西特张 2022-02-25 阅读 32

1.JVM内存结构 

方法区:存放已经加载的类信息,常量,静态变量。即永久代。在1.8中不存在方法区了,被元数据区替代了,原方法区被分为:1.加载的类信息;2.运行时常量池。加载的类信息被保存到元数据区中,运行时常量池保存在堆中。

2.Java内存模型(JMM)

它明确指定了一组排序规则,来保证线程间的可见性。

(1)volatile:保证可见性和有序性;

(2)synchronized:保证可见性(在unlock前写入内存)和有序性(只能一个线程占有锁)。通过管程(Monitor)保证原子性。但是不保证禁止指令重排

代码块的同步是利用monitorenter和monitorexit这两个字节码指令。它们分别位于同步代码块的开始和结束位置。当jvm执行到monitorenter指令时,当前线程试图获取monitor对象的所有权,如果未加锁或者已经被当前线程所持有,就把锁的计数器+1;当执行monitorexit指令时,锁计数器-1;当锁计数器为0时,该锁就被释放了。如果获取monitor对象失败,该线程则会进入阻塞状态,直到其他线程释放锁。
(3)final保证可见性。

3.heap和stack

(1)heap由程序员自己申请,并指明大小;stack由系统分配,存局部变量。

(2)stack是连续的内存结构,默认大小2M;而堆不连续

4.栈溢出

私有,每个方法执行都会创建一个栈,当方法递归可能会出现。通过调整参数-xss调整栈大小。

5.OOM

除了程序计数器,其他都会发生OOM。

(1)栈发生stackoverflowerror,无限创建线程就会发生栈的OOM;(2)常量池在堆中,溢出会发出OutOfMemoryError。(3)堆内存溢出,报错同上;(4)方法区:动态生成大量的类,jsp

(5)直接内存OOM,涉及-XX:MaxDirectMemorySize参数和unsafe对象对内存的申请。

 6.Java常量池

7.判断一个对象是否存活

(1)引用计数法,无法解决循环引用,比如A引用B,B引用A,不采用

(2)可达性分析法:从一个GC Roots对象向下搜索,如果没有任何引用链连接就不可用。

GC Roots对象:(1)方法区静态变量;(2)JVM 栈中引用的对象(3)方法区中常量池引用的对象(4)本地方法栈引用的对象。

还需要两次标记:第一次,判断当前对象有没有finalize()方法,若不存在就记为垃圾等待回收。若有的话进行第二次标记,放入一个队列,生成一个finalize线程执行,执行后仍然没有于GC Roots对象有引用就被回收。

8.四种引用

(1)强引用:如string s=new string

(2)软引用:可有可无,当内存不足就回收,回收后还是不足就抛出内存溢出

(3)弱引用:无论内存足不足都会被回收

(4)虚引用:跟踪垃圾回收对象的活动。

被引用的对象不一定存活,要看引用类型。

9.垃圾回收算法

1.标记清除法:产生不连续的内存碎片,导致大对象分配不了再触发GC

2.标记整理法:适用存活对象多,垃圾少的情况。

3.复制法:将内存分为两块;不会产生内存碎片,缺点内存适用率低。

4.分代收集法:新生代采用复制,老年代标记整理或清除。

10.垃圾回收器

年轻代(复制算法);serial,ParNew,Parallel Scavenge

老年代:标记整理(serial old,parallel old),标记清除(CMS),

年轻代和老年代:G1

11.CMS回收过程

并发标记清除以获取最短回收停顿时间为目标的收集器,在垃圾收集时使得用户线程和GC线程并发执行。

(1)初始标记,仅标记GC ROOT的下一级对象,过程中会STW,但是跟GC ROOT直接关联的对象不多,时间段;

(2)并发标记:根据上一步结果,继续向下直到尽头。过程是多线程的,耗时长,但工资线程不会阻塞,没有STW;

(3)重新标记:标记在第二步中产生的新的垃圾;

(4)并发清除:清除删掉判断已经死亡的对象,由于不需要移动存活对象,所以这个阶段是与用户线程同时并发执行的。

缺点:(1)并发回收导致CPU资源紧张;(2)无法清理浮动垃圾:在并发清理时产生的垃圾只能下一次GC;(3)并发失败,由于并发需要挤出一部分空间给并发回收的程序适用,如老年代92%就触发,而不能100%;(4)内存碎片,可以通过命令在下一次前整理

12.G1回收过程

(1)初始标记(会STW),也是只标记下一级关联的对象

(2)并发标记

(3)最终标记(会STW):对用户线程做短暂的暂停,处理并发阶段结束后任有引用变动的对象。

(4)清理阶段(STW):会更新region的回收价值和成本排序,把决定回收的一部分region复制到空,再清理。这里涉及存活对象的移动,必须暂停用户线程。

13.完整的GC

新生代1/3,老年代2/3;新生代分为Eden,to survivor,from survivor,比例8:1:1;

新生代复制,因为少量对象存活。

 14.空间分配担保机制

如果young GC后存在大量对象存活,而survivor放不下,老年代也放不下。这时老年代就会先检测-xx:HandlePromotionFailure参数是否允许担保失败。允许,判断老年代最大可用连续空间是否大于晋升对象的平均大小,大于就进行young GC,小于就full GC;

15.类加载

类的生命周期:加载,验证,准备(为class对象的静态变量分配内存并初始化),解析(符号引用转换为直接引用),初始化(调用类构造器的过程),适用和卸载。其中,验证准备解析称为连接。

加载过程:(1)通过类的全限定性类名获取类的二进制流;(2)转为方法区的运行时数据结构;(3)再堆中生成一个class对象。

16.类加载器:启动类加载器(加载Java核心类库),扩展类加载器(加载Java扩展库),系统类加载器(加载我们自己写的应用类),自定义类加载器(继承自class loader)

17.双亲委派机制

防止内存中出现多个相同的字节码;因为如果没有双亲委派,用户就可以自己定义一个String类,无法保证类的唯一性。

打破:自定义类加载器,继承class loader,重写loadclass和findclass方法。

 

 18.JVM调优命令:

(1)jsp:JVM 显示指定系统内所有的hotspot虚拟机进程。

(2)jstate:监控虚拟机运行时状态信息的命令

(3)jmap:生成heap dump文件。或者-XX:HeapDumpOnOutOfMemoryError让OOM时自动生成dump文件。还可以查询finalize执行队列,堆的适用和哪种收集器。

(4)jhat:和jmap一起适用,分析jmap生成的dump文件,一般把dump文件复制到浏览器查看

(5)jstack:生成虚拟机当前时刻的线程快照,查看各个线程的调用堆栈

 

举报

相关推荐

JVM的整理

JVM - GC整理

jvm 调优整理

JVM内存模型整理

JVM核心参数图解-整理

【面经】JVM零散整理

jvm基础理论知识整理

0 条评论