您好,我是湘王,这是我的CSDN博客,欢迎您来,欢迎您再来~
这是多年之前做过的学习笔记,今天再翻出来,觉得仍然是记忆犹新。「独乐乐不如众乐乐」,就拿出来分享给「众乐乐」吧。
目前大多数Java工程师都面临一个共同的问题:对JVM的了解非常贫乏,尤其是对实际生产环境中的优化几乎就是完全没有任何经验。加上JVM的相关资料也较为稀缺,完全没有任何真正系统化讲解JVM生产实践的技术资料。
这里聚集了多个真实的JVM优化案例,每个案例都从背景开始,通过现场故障还原,一步步分析、排查和定位每个问题,包括解决问题的过程中涉及到的底层JVM原理的剖析。同时通过大量真实案例的手动实践和演练,逐步积累起丰富的排查经验。
通过这种分析、思考、动手及反复练习的方式,培养工程师的思维能力和动手能力,最终让每个工程师都有如下能力:
1、可以在指导和协助下完成所负责项目的JVM优化;
2、遇到线上生产环境问题,至少可以有思路、方法和手段去定位、分析、排查、解决,而不是茫然无措;
3、清楚该怎么动手,也明白背后的JVM底层原理;
4、至少有一些真实或接近真实案例的经验积累。
启动一个JVM进程时,JVM会经历如下过程:
也就是:
当需要用到它的时候再加载,而不是从一开始就加载进来。这其实就是单例模式中的「懒汉模式」:
在验证阶段,JVM会校验加载进来的.class文件是否符合规范:
验证完毕之后,在准备阶段会给类及(包括static修饰的)变量分配内存空间(仅仅是分配并给一个默认的初始值):
而到了解析阶段,会把符号引用替换为直接引用:
所以,在初始化阶段,JVM会进行类初始化及准备静态代码块(准备阶段的变量在此赋值)。那什么时候初始化一个类呢?以下时机一定会进行初始化动作:
1、new Object();
2、包含main()方法的类;
3、如果某个类的父类还未初始化,那就必须要先初始化其父类。
初始化过程:
到了类加载器这一步,Java中有这么几种类加载器:
1、Bootstrap ClassLoader:启动类加载器,加载Java核心类(lib中的类);
2、Extension ClassLoader:扩展类加载器,加载lib\ext中的类;
3、Application ClassLoader:应用程序类加载器,加载ClassPath环境变量;所指定路径中的类;
4、自定义类加载器:根据用户自定义需求加载类。
这会涉及到JVM的「双亲委派机制」。所谓「双亲委派机制」就是:
1、先顺着继承结构往上,由父类加载所需要的类;
2、当父类没找到要加载的类时,再顺着集成结构向下,由子类加载。
OK,看到这里,可以再把JVM的类加载过程回想一遍是怎样的了。
感谢您的大驾光临!咨询技术、产品、运营和管理相关问题,请关注后留言。欢迎骚扰,不胜荣幸~