双亲委派机制

image.png

image.png
当一个Hello.class这样的文件要被加载时。不考虑我们自定义类加载器,首先会在AppClassLoader中检查是否加载过,如果有那就无需再加载了。如果没有,那么会拿到父加载器,然后调用父加载器的loadClass方法。父类中同理也会先检查自己是否已经加载过,如果没有再往上。注意这个类似递归的过程,直到到达Bootstrap classLoader之前,都是在检查是否加载过,并不会选择自己去加载。直到BootstrapClassLoader,已经没有父加载器了,这时候开始考虑自己是否能加载了,如果自己无法加载,会下沉到子加载器去加载,一直到最底层,如果没有任何加载器能加载,就会抛出ClassNotFoundException。
————————————————
版权声明:本文为CSDN博主「IT烂笔头」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/codeyanbao/article/details/82875064

jvm内存模型

image.png
image.png

jvm内存划分

image.png

如何解决线上频繁gc

image.png

oom原因

image.png

java类加载和初始化过程

image.png
image.png

何时触发Young GG

如果Eden区域没有足够的空间,那么就会触发YGC(Minor GC)。

对象什么时候进入老年代

① YGC时,To Survivor区不足以存放存活的对象,对象会直接进入到老年代。
② 经过多次YGC后,如果存活对象的年龄达到了设定阈值(默认15),则会晋升到老年代。
③ 动态年龄判定规则:按照年龄从小到大对其所占用的大小进行累积,当累积的某个年龄大小超过了survivor区的一半 时,取这个年龄和MaxTenuringThreshold(默认15)中更小的一个值,作为新的晋升年龄阈值,下次Minor GC,此年龄及以上的对象直接进入老年代。
④ 大对象:由-XX:PretenureSizeThreshold启动参数控制(默认不限制),若对象大小大于此值,直接进入老年代。

何时触发Full GC

① 老年代的内存使用率达到了一定阈值(默认92%),直接触发FGC。
② 在YGC之前,会先检查“老年代最大可用的连续空间<新生代所有对象的总空间”,如里小于,进一步检查“老年代 最大可用的连续空间<新生代历次晋升入老年代的对象总和的平均大小”,如果小于,则触发Full GC。
③ Metaspace(元空间)在空间不足时会进行扩容,当扩容到了-XX:MetaspaceSize 参数的指定值时,也会触发FGC。
④ System.gc() 或者Runtime.gc() 被显式调用时,触发FGC。

CMS收集器缺点

CMS收集器对处理器资源非常敏感
CMS追求的是回收停顿时间尽可能短,为了达到这种目的,引入了并发标记和并发清除,即GC线程和用户线程并发执行。在并发阶段处理器需要分出一部分资源执行GC线程,这会导致应用程序变慢,总吞吐量降低。
默认情况下CMS启动的回收线程数是:(处理器核数+3)/4.
这里分两种情况:
1)处理器个数小于等于4个
Jvm面试题 - 图10
可以看出随着处理器个数越来越小,GC线程占比会越来越大。
2)处理器个数大于四个
image.png
随着处理器核数的不断增加,GC线程占比会不断下降。

CMS收集器无法处理“浮动垃圾”
并发标记时会出现有些已经死亡的对象被标记成存活,从而逃过垃圾回收,这部分应该被回收而没有被回收的对象就是“浮动垃圾”。
CMS收集器会造成内存碎片
CMS收集器使用的是标记清除算法

三色标记算法

image.png
三色标记法(标记-清除算法中标记采用的算法)问题:
问题1:产生浮动垃圾:当B指向D的指针消失时,d扫不到了,但是没关系,下次重新扫描可以扫到D;

问题2:漏标
image.png
这时候导致不会扫描D;解决方法:当A增加引用别的对象时,把A降为灰色;
image.png