• 当前位置: 首 页 > 教育百科 > 学历/技能 > 正文

    解锁JVM成神之路(一)

    :2019年10月10日
    小白学java

    jvm指的是Java虚拟机,一种能够运行Java字节码的虚拟机。它能够模拟具有完整硬件系统功能,运行在一个完全隔离环境中的完整计算机系统。作为一种编程语言的虚拟机,它不只是专注于Java语言,只要生成编译...

    jvm指的是Java虚拟机,一种能够运行Java字节码的虚拟机。它能够模拟具有完整硬件系统功能,运行在一个完全隔离环境中的完整计算机系统。作为一种编程语言的虚拟机,它不只是专注于Java语言,只要生成编译文件匹配jvm对加载编译文件格式的要求,任何语言都可以由jvm编译运行。比如scala,kotlin等。

    一,JVM的基本组成结构。

    jvm由三部分组成:

    1)类加载子系统

    2)运行时数据区(内存空间,内存结构)

    3)执行引擎

    结构图如下:

    点击添加图片描述(最多60个字)

    深入了解运行时数据区:

    线程共享:

    ①方法区(1.8之后已经不叫方法区了,叫元数据区):用来存储被jvm加载的类信息,常量,静态变量等数据。也就是类的所有属性,方法以及构造器,接口代码都在这里定义。

    这个区域包含一个很重要的区域叫常量池。class对象除了类的版本,属性,方法等信息外,还有一些常量以及字面值,而这些几乎都存在于常量池里,这部分内容将在被加载的过程中存放到常量池里。

    ②堆:实例化的对象以及数组都存在这个区域。这个区域的cg最活跃,也就是cg进行垃圾回收的重要场所。这个区域,cg是以分代回收算法进行垃圾回收的。从cg的角度看,堆又可以分为:新生代和老年代。

    线程私有:

    ③程序计数器:也就是一个指针,指向方法区中的方法字节码。也就是用于存储每条线程的执行字节码指令地址。每条线程都会拥有自己的程序计数器,以便线程切换的时候,能使程序正常运行。

    ④jvm栈:存储着每一个栈帧。每个方法的执行都对应着每一个栈帧,栈帧里放着局部变量表,操作数栈,动态连接,方法出口等信息。每个方法的执行以及结束都对应到栈帧的入栈与出栈。

    ⑤本地方法栈:这个跟jvm栈差不多,只是jvm栈为我们的java服务的,而本地方法栈是为native 方法服务。

    深入了解类加载子系统:

    我们的Java文件被jvm编译器编译成class对象之后,在runtime时,由类加载子系统将class字节码文件加载到运行时数据区中。

    但是,类加载子系统在类的整个生命周期中主要的工作是什么呢?

    类的生命周期:

    类的生命周期分为:

     加载-->连接-->初始化-->使用-->卸载

    而连接过程又分为:验证-->准备-->解析。其实这个过程就是类加载子系统工作的过程。

    一,工作过程

    1,加载:将class字节码文件加载到运行时数据区中。

    2.1,验证:1,检查字节码文件是否正确。2,检查文件头的magic number是否正确。

    何为magic number?我们用编辑器打开随意一个class文件,发现都是以CAFEBABE开头。把这数据改掉或者删除,都会出错。这个就是magic number

    2.2,准备:给类的静态变量分配内存,赋予初始值。这里的初始值并不是赋值的值。打个比方:private int i = 100; 在准备阶段,并不是将100赋值给i。而是给i赋值0,因为int的默认初始值是0。

    2.3)解析:检查指定的类是否引用了其他的类或者接口,是否能正常引入。也就是装载当前类引入依赖的其他类。

    3)初始化:这里才是给类的静态变量赋正确的初始值。i的值由0变为100。

    使用,卸载这就没什么可说的了。

    通过源码了解加载过程:

    在rt.jar包中的java.lang.ClassLoader类中,我们可以查看类加载实现过程的代码,具体源码如下:

    protected Class<?> loadClass(String name, boolean resolve)

    throws ClassNotFoundException

    {

    synchronized (getClassLoadingLock(name)) {

    // First, check if the class has already been loaded

    Class<?> c = findLoadedClass(name);

    if (c == null) {

    long t0 = System.nanoTime();

    try {

    if (parent != null) {

    c = parent.loadClass(name, false);

    } else {

    c = findBootstrapClassOrNull(name);

    }

    } catch (ClassNotFoundException e) {

    // ClassNotFoundException thrown if class not found

    // from the non-null parent class loader

    }

    if (c == null) {

    // If still not found, then invoke findClass in order

    // to find the class.

    long t1 = System.nanoTime();

    c = findClass(name);

    // this is the defining class loader; record the stats

    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);

    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);

    sun.misc.PerfCounter.getFindClasses().increment();

    }

    }

    if (resolve) {

    resolveClass(c);

    }

    return c;

    }

    }

    源码的注释写得很清楚了:

    1)加载的时候使用了synchronized加锁机制,也就是当前线程有在加载当前这个类时,不允许其他类进行加载。

    2)判断这个类是否已经被加载,如果已经加载了,就不再加载。如果没有,则要加载。

    我们在看源码时,看到

     //从parent这个成员变量中,我们得知

     private final ClassLoader parent;

    try {

    if (parent != null) {

    c = parent.loadClass(name, false);

       } else {                        

          c = findBootstrapClassOrNull(name);                    

       }                

      }

    这是一个很重要的信息~由此引申一个很重要的概念

    二,双亲委派机制

    我们先了解类加载器的种类:

    1,启动类加载器Bootstrap ClassLoader:负责将java_home/lib下的类加载到内存中

    2,扩展类加载器Extension ClassLoader:负责将java_home/lib/extde的类加载到内存中

    3,系统类加载器Application ClassLoader:负责将classpath的类加载到内存中

    4,用户自定义加载器User ClassLoader:负责加载用户自定义路径下的类包

    在看源码可以看出,每次加载类的时候,当前加载器都将该类一层一层交给parent,而且每次都检查是否已经加载了,如果加载了就不再加载。当交给parent时,如果parent能加载,则就加载。如果parent都不能加载,则由当前加载器进行加载。

    双亲委派的优势:

    沙箱安全机制:比如自己写的String.class类不会被加载,这样可以防止核心库被随意篡改

    避免类的重复加载:当父ClassLoader已经加载了该类的时候,就不需要子CJlassLoader再加载一次

    以上就是jvm的内存结构以及类加载子系统的相关内容。jvm还有许许多多的知识,比如垃圾回收机制,调优等,以后我们慢慢了解

    [编辑:王振袢 &发表于江苏]
    [我要纠错]

    来源:本文内容搜集或转自各大网络平台,并已注明来源、出处,如果转载侵犯您的版权或非授权发布,请联系小编,我们会及时审核处理。
    声明:江苏教育黄页对文中观点保持中立,对所包含内容的准确性、可靠性或者完整性不提供任何明示或暗示的保证,不对文章观点负责,仅作分享之用,文章版权及插图属于原作者。

    关键词: 指的 Java 虚拟 一种 能够
    有价值
    0
    无价值
    0
    猜您喜欢
    最热文章

    暂不支持手机端,请登录电脑端访问

    正在加载验证码......

    请先完成验证