学完了这篇JVM,面试官真拿我没办法了! (3)

前面我们说到每个类会有一个对应的类加载器去加载这个类,而不同的类加载器所加载的类的类型不同,当我们要加载一个类的时候首先会去应用程序类加载器加载过的集合里(注:这里是加载过的集合里)查看有没有加载这个类,如果没有就去扩展类加载器加载过的集合里查看有没有加载过这个类,如果没有就再向上去找引导类加载器加载过的集合里看有没有加载过这个类,如果也没有就会从引导类加载器要加载的核心类中寻找有没有要加载的类,如果没有就向下寻找扩展类加载器中要加载的扩展类中有没有,如果也没有就去应用程序加载器中寻找。

好处:

1、不会重复去加载一个类,假如应用程序类加载器加载过Student类,那么下载再加载这个类的时候只需要判断应用程序类加载过的集合里有没有加载过这个类,如果加载过就不用再次加载了。

2、防止恶意修改核心类库,比如我们自己写一个String类,我们去运行这个类,系统会在引导类加载器中加载Java的核心类库中的String类,而不会加载我们自定义个的String类,这就防止我们私自篡改核心类库。

七、JVM堆内存模型

file

在JVM中我们的堆内存模型大概为图所示,我们新生成的对象会放到eden区,当我们eden区域放满了,我们会进行一个轻GC,会把eden区域和S0区域的存活对象放到S1区域,然后将eden区域和S0区域清空,然后新生成的对象接着放到eden区域,当eden区域再次满了,会将eden区域和S1区域的存活对象放到S0区域,然后将eden区域和S1区域清空,如此循环往复,没进行一次循环会将没有被清除的对象年龄+1,如果存活的对象年龄到达15(这个数值可以调整),就会将此对象放到老年代,或者是survivor区域满了也会将一些对象放到老年代,如果当老年代满了就会进行一次重GC。

八、JVM调优

所谓JVM调优主要就是减少堆内存中重GC的次数,这样我们就根据对象什么情况会进入老年代来进行分析,首先是存活15代(这个数值可以调整),这种情况一般就是一些常量等,这些一般不会有再大的优化空间,或者一些代码的问题造成循环调用,这种情况通过修改调整代码即可。其次是当survivor区域满了的话就会向老年代放入一些对象,这个时候我们就需要根据业务情况来调整堆内存的大小以及年轻代和老年代的比例,一般我们例如一些电商系统,一些订单对象进入内存中就是朝生夕是,订单从创建到持久化数据库中就不在内存中使用了,所以一些正常的业务产生的对象会在轻GC的时候被收回,但是有一些大对象可能放不下年轻代中所以就会放入老年代,这种情况我们就要调大堆内存中年轻代的大小,使得一些大对象可以放入到年轻代中,并随着轻GC被垃圾收集器收回。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwpysp.html