Learning route recommendation, how to gnaw down the mountain of JVM (End)

Hello everyone , I'm Xiaofu~

This is the sixth article about the JVM. I wrote five articles about the JVM before, all of which will lead you to understand the JVM layer by layer. The basic knowledge of the JVM has been explained.

Then this article will be the last article of the JVM, with a summary and supplementary knowledge points that have not been mentioned.

First of all, about the opening of the JVM, the article on how to read the third edition of the JVM virtual machine: How to read "The third edition of the JVM virtual machine" in three days , mainly to share the personal experience of reading this divine book, in the article Focus on it and absorb the knowledge points we need.

Then, the second article I wrote a long time ago about the JVM's runtime data area and GC algorithms: Still learning JVM? I've summed it up for you (with a brain map) .

This article is the key part of the theory, because this piece is about what the various parts of the JVM's runtime data area do, as well as the generation theory of the key JVM heap and the basic recovery algorithm of GC , which are all for the following Java heap. The tuning practice is to pave the way.

Then there is the third article, which is also the top priority of tuning. The main topic is GC: Are you rubbish and have no points in your heart? , how to judge whether an object is alive, as well as the common types of GC, the common collocation of GC young generation and old generation, the principles and characteristics of various GC, and applicable scenarios are mentioned in the article.

After having the second run-time data area and the theoretical basis of the third GC, then the fourth chapter of JVM tuning practice chapter one: JVM tuning practice chapter one , this article mainly focuses on JVM tuning practice , including the online Arthas tool, GUI tool (Visual VM), memory analysis tool (mat), and the explanation and use of linux's original commands such as jps, jstack, jstat, jmap, jhat and other commands .

After getting familiar with JVM tuning tools, the fifth chapter is the final actual tuning scenarios, cases, classic OOM, disk shortage, CPU soaring, deadlock, and tuning purposes and theory. Excellent case scenario analysis : JVM performance tuning in practice (2)

Among them, the fifth article is also the longest article I have written, and it is also the one with a lot of dry goods, and it is also the most purposeful one. Learning JVM is for tuning, and it also gains the attention of many new readers.

Therefore, according to the order arranged for you above, reading one by one, it should be helpful to have a deep understanding of your tuning techniques and theories.

Then, if you have time, you can also read "In-depth JVM Virtual Machine Third Edition" by yourself. For other books on JVM, I recommend: "Java Virtual Machine Specification", "Garbage Collection Algorithm Manual: Automatic Memory Management" Art" and "Virtual Machines: Versatile Platforms for System and Processes" are several good books, you can read them if you have the time and ability.

Finally, this is the last and sixth article. For the part we need for the JVM virtual machine, there is another part that is the class loading subsystem that has not yet been explained, so for the integrity of the article, this supplements the JVM's class loading subsystem. , this one is mostly theoretical.

Class Loading Subsystem Overview

首先,我们来聊一聊JVM的类加载子系统,我们知道我们的代码敲完后是.java类,然后经过编译就会变成.class类型的字节码文件。

这些.class类型的字节码文件经过类加载系统加载到JVM的内存中来供我们使用,这些文件我们也成为了元数据。

下面我画了一张图来大概一个类被类加载系统加载的过程,供大家理解:

就这样一个java类经过上面层层的过程来到了我们的JVM的虚拟机中,首先在加载过程的.class文件可以来源终于下面几个方面:

  • 从系统文件中获取,比如从我们本地编译好的class。
  • 从网络中获取
  • 或者运行时计算出来的,比如使用动态代理技术,运行时生成。
  • 或者由其他的文件生成,比如jsp生成对应的class文件。

当由我们的类加载子系统完成了类加载后,这部分信息(包括类信息、常量、静态变量、方法信息等)就会存在方法区的内存中(jdk 7以及以前,jdk 8及以上移动到元空间,本地内存中),然后由JVM的执行引擎来执行。

在这个过程类加载的过程就好像扮演着中间人的角色,目的为的是JVM的执行引擎能够执行这些类:.class -> JVM -> 元数据模板 -> 实例对象

那么,JVM在加载类的时候,这个过程的主角类加载器,又是怎么工作的呢?下面我们来聊一聊类加载器。

类加载器

在JVM中经典的类加载器分为如下三层:

  1. 启动类加载器(BootStrap ClassLoader):该加载器是由C++实现,加载<JAVA_HOME>\lib下的文件,这类加载起不会被Java程序所直接使用,该类加载器一般加载包名为java、javax、sun等开头的类
  2. 扩展类加载器(Extension ClassLoader):扩展类加载器是加载<JAVA_HOME>\lib\ext目录下的资源,它可以用来扩展Java SE的功能,如果用户创建的JAR包放在此目录下,就会被扩展类加载器加载
  3. 应用类加载器(Application ClassLoader):它负责加载用户类路径(ClassPath)上的所有类库,开发者同样可以直接在代码中使用这个类加载器。


除了上面的经典三层还有一个就是用户自定义类加载器(User ClassLoader),它可以在程序中加载自己需要的类,所以完整的JVM类加载器如下图所示:

他们的关系并不是继承的关系,而是通常以组合的关系来复用父类加载器的代码。

类加载过程

我们了解完各种类加载器后,接下来详细的了解类加载的过程,一个完整的类加载过程主要包括一下几个阶段:加载-> 验证->准备->解析->初始化

加载阶段是通过类的全类名,然后通过类加载器将class文件的二进制字节流转化为运行时数据区的方法区中。

并且,会在内存中生成一个java.lang.Class对象,作为这个类的各种数据的访问入口。

验证阶段既是验证字节码class文件中的字节码是否服务规范,保证里面的字节码不会对JVM自身造成伤害。

准备阶段既是为类中的类变量(static修饰的变量,但没有被final修饰一起修饰)分配内存以及初始化类变量的零值,这里并不包括实例变量,实例变量是在对象一起分配在Java堆中。

所谓的零值也就是数据的默认初始值,比如int为0,boolean默认为false,float默认为0.0f,引用类型的默认为null。

解析阶段的作用是将虚拟机内的常量池的符号引用替换为直接引用的过程。所谓的符号引用就是可以是任何形式的字面量,只要能够定位到目标即可;而直接引用可以是指向目标的指针、相对偏移量间接定位到目标的句柄。

最后是初始化,初始化是类加载的最后一个阶段,也是在这个阶段,Java虚拟机才真正开始执行类中的Java程序代码。

上面说到在准备阶段变量已经初始化一次零值了,那么在这一阶段才会将变量初始化为程序代码中主观设置的值。

对于这一部分,我之前也写过一篇详细的,所以这里做一个大概的介绍,详细的可以参考这一篇文章:面试官:你知道java类是怎么跑起来的吗?问的我一脸懵

双亲委派原则

双亲委派原则是各种加载器之前的一种工作方式,它目的是为了实现更加高效的进行类的加载。

当一个类加载器收到加载类的请求时,不会自己去尝试先加载该类,而是把该加载请求委托给父类,若是没有父类就是直接找顶层类加载器,若是有父类,并且父类还有父类加载器,依次向上委托,直到上面的所有父类都无法完成加载是,才会自己去加载,若是加载失败就会抛出异常。

它的好处就是加载一个类时,不用重复加载,当父类已经加载了,就不用加载第二年份,保证内存中只有一份。

我们来看看双亲委派实现的源代码,它的源代码主要实现是java.lang.ClassLoader的loadClass() 方法中:

protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
 // 检查该类是否已经被加载过了
 Class c = findLoadedClass(name);
 // c为null没有被加载过,则使用双亲委派原则进行类加载
 if (c == null) {
  try {
      // 存在父类加载器
   if (parent != null) {
    c = parent.loadClass(name, false);
   } else {
       // 不存在服务加载器,则直接使用顶层类加载器进行加载
    c = findBootstrapClassOrNull(name);
   }
  } catch (ClassNotFoundException e) {
   // 父类加载抛出异常,说明父类无法完成加载
  }
  if (c == null) {
   // 父类无法完成加载,则尝试自己去完成加载动作
   c = findClass(name);
  }
 }
 if (resolve) {
  resolveClass(c);
 }
 return c;
}

好了,这一篇文章是的主要内容也讲完了,文字比较短,没有像以前那样基本都是万字,因为主要的内容都已经讲完了,这一篇还是比较简单的,更加倾向于对以前写的JVM的文章的总结。


接下来的文章开始数据库的连载,主要个人看的书籍是 《Mysql 45讲》、《MySQL技术内幕  InnoDB存储引擎  第2版》、《高性能mysql第三版》,好了这一期就到这里,我们下一期间。

我是小富~,如果对你有用在看关注支持下,咱们下期见~


   
   
   
   
   
你的每个赞和在看,我都喜欢!

本文分享自微信公众号 - 程序员内点事(chengxy-nds)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

{{o.name}}
{{m.name}}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324131304&siteId=291194637