加入收藏 | 设为首页 | 会员中心 | 我要投稿 威海站长网 (https://www.0631zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 资源网站 > 空间 > 正文

对JVM还有什么不懂的?带你深入浅出JVM!

发布时间:2019-10-15 17:36:25 所属栏目:空间 来源:java互联网架构
导读:JVM JVM = 类加载器(classloader) + 执行引擎(execution engine) + 运行时数据区域(runtime data area) 下面这幅图展示了一个典型的JVM(符合JVM Specification Java SE 7 Edition)所具备的关键内部组件。 组件中的多线程处理 多线程处理或自由线程处理指的

实例化 类或接口,包含执行类或接口的实例化方法:

对JVM还有什么不懂的?资深架构师一篇文章带你深入浅出JVM!

在JVM中存在多个不同职责的类加载器。每一个类加载器都代理其已被加载的父加载器(除了bootstrap类加载器,因为它是根加载器)。

Bootstrap类加载器:当java程序运行时,java虚拟机需要装载java类,这个过程需要一个类装载器来完成。而类装载器本身也是一个java类,这就出现了类似人类的第一位母亲是如何产生出来的问题。

其实,java虚拟机中内嵌了一个称为Bootstrap的类装载器,它是用特定于操作系统的本地代码实现的,属于java虚拟机的内核,这个Bootstrap类装载器不用专门的类装载器去装载。Bootstrap类装载器负责加载java核心包中的类。

Extension 类加载器:从标准的Java扩展API中加载类。例如,安全的扩展功能集。

System 类加载器:这是应用程序默认的类加载器。它从classpath中加载应用程序类。

用户定义的类加载器:可以额外得定义类加载器来加载应用程序类。用户定义的类加载器可用于一些特殊的场景,比如:在运行时重新加载类或将一些特殊的类隔离为多个不同的分组(通常web服务器中都会有这样的需求,比如Tomcat)。

更快的类加载

一个称之为类数据共享(CDS)的特性自HotspotJVM 5.0开始被引进。在安装JVM期间,安装器加载一系列的Java核心类(如rt.jar)到一个经过映射过的内存区进行共享存档。CDS减少了加载这些类的时间从而提升了JVM的启动速度,同时允许这些类在不同的JVM实例之间共享。这大大减少了内存碎片。

方法区的位置

JVM Specification Java SE 7 Edition清楚地声明:尽管方法区是堆的一个逻辑组成部分,但最简单的实现可能是既不对它进行垃圾回收也不压缩它。然而矛盾的是利用jconsole查看Oracle的JVM的方法区(以及CodeCache)是非堆形式的。OpenJDK代码显示CodeCache相对ObjectHeap而言是VM中一个独立的域。

类加载器引用

类通常是按需加载,即第一次使用该类时才加载。由于有了类加载器,Java运行时系统不需要知道文件与文件系统。

运行时常量池

JVM对每个类型维护着一个常量池,它是一个跟符号表相似的运行时数据结构,但它包含了更多的数据。Java的字节码需要一些数据,通常这些数据会因为太大而难以直接存储在字节码中。取而代之的一种做法是将其存储在常量池中,字节码包含一个对常量池的引用。运行时常量池主要用来进行动态链接。

几种类型的数据会存储在常量池中,它们是:

  • 数值字面量
  • 字符串字面量
  • 类的引用
  • 字段的引用
  • 方法的引用

如果你编译下面的这个简单的类:

  1. package org.jvminternals;public class SimpleClass { public void sayHello() {System.out.println("Hello");}} 

生成的类文件的常量池,看起来会像下图所示:

  1. Constant 
  2.  pool: #1 = Methodref #6.#17 // java/lang/Object."<init>":()V#2 =  
  3. Fieldref #18.#19 // java/lang/System.out:Ljava/io/PrintStream;#3 =  
  4. String #20 // "Hello"#4 = Methodref #21.#22 //  
  5. java/io/PrintStream.println:(Ljava/lang/String;)V#5 = Class #23 //  
  6. org/jvminternals/SimpleClass#6 = Class #24 // java/lang/Object#7 = Utf8  
  7. <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Utf8 LineNumberTable #11 
  8.  = Utf8 LocalVariableTable #12 = Utf8 this #13 = Utf8  
  9. Lorg/jvminternals/SimpleClass; #14 = Utf8 sayHello #15 = Utf8 SourceFile 
  10.  #16 = Utf8 SimpleClass.java #17 = NameAndType #7:#8 //  
  11. "<init>":()V#18 = Class #25 // java/lang/System#19 = NameAndType  
  12. #26:#27 // out:Ljava/io/PrintStream;#20 = Utf8 Hello #21 = Class #28 //  
  13. java/io/PrintStream#22 = NameAndType #29:#30 //  
  14. println:(Ljava/lang/String;)V#23 = Utf8 org/jvminternals/SimpleClass #24 
  15.  = Utf8 java/lang/Object#25 = Utf8 java/lang/System #26 = Utf8 out#27 =  
  16. Utf8 Ljava/io/PrintStream; #28 = Utf8 java/io/PrintStream #29 = Utf8  
  17. println #30 = Utf8 (Ljava/lang/String;)V 

(编辑:威海站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读