`

JVM初步探索

阅读更多

JVM体系结构
1、类装载器(ClassLoader)子系统
    用来转载.class文件
2、执行引擎
    执行字节码,或者执行本地方法
3、运行时数据区
    方法区,堆,java栈,PC寄存器,本地方法栈

            JVM体系结构之类加载器
类加载过程
1、转载
    装载过程负责找到二进制字节码并加载至JVM中,JVM通过类名、类所在的包名通过ClassLoader来完成类的加载,同样也可采用以上三个元素来标示一个加载的类类名+包名+ClassLoader实例ID
2、链接
    连接过程负责对二进制字节码的格式进行校验,初始化装载类的静态变量以及解析类中调用的接口、类。
    在转成校验后,JVM初始化类中的静态变量,并将其值赋为默认值。
    最后一步为对类中的所有属性、方法进行验证,以确保其需要调用的属性、方法存在,以及具备应有权限(例如public、private域权限),会造成NoSuchMethodError、NoSuchFieldError等错误信息。
3、初始化
    初始化过程即为执行类中的静态初始化代码、构造器代码以及静态属性的初始化,在四种情况下初始化过程会被触发执行:
调用new;反射调用类中的方法;子类调用了初始化;JVM其中过程中指定的初始化类。

类加载器种类
一、包括类装载器和用户自定义类加载器,启动类装载器是JVM实现的一部分,用户自定义装载器则是Java程序的一部分,必须是ClassLoader的子类。
二、 主要分为以下几类:
(1) Bootstrap ClassLoader
      这是JVM的根ClassLoader,它是用C++实现的,JVM启动时初始化此ClassLoader,并由此ClassLoader完成$JAVA_HOME中jre/lib/rt.jar(Sun JDK的实现)中所有class文件的加载,这个jar中包含了java规范定义的所有接口以及实现。
(2) Extension ClassLoader
     JVM用此classloader来加载扩展功能的一些jar包
(3) System ClassLoader
      JVM用此classloader来加载启动参数中指定的Classpath中的jar包以及目录,在Sun JDK中ClassLoader对应的类名为AppClassLoader。
(4) User-Defined ClassLoader
       User-DefinedClassLoader是Java开发人员继承ClassLoader抽象类自行实现的ClassLoader,基于自定义的ClassLoader可用于加载非Classpath中的jar以及目录
三、ClassLoader抽象类提供了几个关键的方法:
(1)loadClass
      此方法负责加载指定名字的类,ClassLoader的实现方法为先从已经加载的类中寻找,如没有则继续从parent ClassLoader中寻找,如仍然没找到,则从System ClassLoader中寻找,最后再调用findClass方法来寻找,如要改变类的加载顺序,则可覆盖此方法
(2)findLoadedClass
    此方法负责从当前ClassLoader实例对象的缓存中寻找已加载的类,调用的为native的方法。
(3) findClass
    此方法直接抛出ClassNotFoundException,因此需要通过覆盖loadClass或此方法来以自定义的方式加载相应的类。
  (4) findSystemClass
    此方法负责从System ClassLoader中寻找类,如未找到,则继续从Bootstrap ClassLoader中寻找,如仍然为找到,则返回null。
  (5)defineClass
    此方法负责将二进制的字节码转换为Class对象
  (6) resolveClass
  此方法负责完成Class对象的链接,如已链接过,则会直接返回。

            JVM体系结构之执行引擎
一、JVM通过执行引擎来完成字节码的执行,在执行过程中JVM采用的是自己的一套指令系统,每个线程在创建后,都会产生一个程序计数器(pc)和栈(Stack),其中程序计数器中存放了下一条将要执行的指令,Stack中存放Stack Frame,表示的为当前正在执行的方法,每个方法的执行都会产生Stack Frame,Stack Frame中存放了传递给方法的参数、方法内的局部变量以及操作数栈,操作数栈用于存放指令运算的中间结果,指令负责从操作数栈中弹出参与运算的操作数,指令执行完毕后再将计算结果压回到操作数栈,当方法执行完毕后则从Stack中弹出,继续其他方法的执行。

      在执行方法时JVM提供了invokestatic、invokevirtual、invokeinterface和invokespecial四种指令来执行
     (1)invokestatic:调用类的static方法
     (2) invokevirtual: 调用对象实例的方法
     (3) invokeinterface:将属性定义为接口来进行调用
     (4) invokespecial: JVM对于初始化对象(Java构造器的方法为:<init>)以及调用对象实例中的私有方法时。
二、执行技术
    主要的执行技术有:解释,即时编译,自适应优化、芯片级直接执行
    (1)解释属于第一代JVM,
    (2)即时编译JIT属于第二代JVM,
    (3)自适应优化(目前Sun的HotspotJVM采用这种技术)则吸取第一代JVM和第二代JVM的经验,采用两者结合的方式
   
    (4)自适应优化:开始对所有的代码都采取解释执行的方式,并监视代码执行情况,然后对那些经常调用的方法启动一个后台线程,将其编译为本地代码,并进行仔细优化。若方法不再频繁使用,则取消编译过的代码,仍对其进行解释执行。

            JVM运行时数据区

第一块: PC寄存器
      PC寄存器是用于存储每个线程下一步将执行的JVM指令,如该方法为native的,则PC寄存器中不存储任何信息。

  第二块:JVM栈
      JVM栈是线程私有的,每个线程创建的同时都会创建JVM栈,JVM栈中存放的为当前线程中局部基本类型的变量(java中定义的八种基本类型:boolean、char、byte、short、int、long、float、double)、部分的返回结果以及Stack Frame,非基本类型的对象在JVM栈上仅存放一个指向堆上的地址

  第三块:堆(Heap)
       Heap是大家最为熟悉的区域,它是JVM用来存储对象实例以及数组值的区域,可以认为Java中所有通过new创建的对象的内存都在此分配,Heap中的对象的内存需要等待GC进行回收。
    JVM将Heap分为New Generation和Old Generation(或Tenured Generation)两块来
进行管理:
(1)New Generation
        又称为新生代,程序中新建的对象都将分配到新生代中,新生代又由Eden Space和两块Survivor Space构成,可通过-Xmn参数来指定其大小
(2) Old Generation
       又称为旧生代,用于存放程序中经过几次垃圾回收还存活的对象,例如缓存的对象等,旧生代所占用的内存大小即为-Xmx指定的大小减去-Xmn指定的大小。
  第四块:方法区域(Method Area)
       (1)方法区域存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,当开发人员在程序中通过Class对象中的getName、isInterface等方法来获取信息时,这些数据都来源于方法区域,可见方法区域的重要性,同样,方法区域也是全局共享的,在一定的条件下它也会被GC,当方法区域需要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。
       (2)在Sun JDK中这块区域对应的为Permanet Generation,又称为持久代,默认为64M,可通过-XX:PermSize以及-XX:MaxPermSize来指定其大小。

 第五块:运行时常量池(Runtime Constant Pool)
       类似C中的符号表,存放的为类中的固定的常量信息、方法和Field的引用信息等,其空间从方法区域中分配。

第六块:本地方法堆栈(Native Method Stacks)
       JVM采用本地方法堆栈来支持native方法的执行,此区域用于存储每个native方法调用的状态。
            JVM体系结构之内存回收
一、 JVM中自动的对象内存回收机制称为:GC(Garbage Collection)

1、 GC的基本原理:
      为将内存中不再被使用的对象进行回收,GC中用于回收内存中不被使用的对象的方法称为收集器,由于GC需要消耗一些资源和时间的,Java在对对象的生命周期特征进行分析后,在V 1.2以上的版本采用了分代的方式来进行对象的收集,即按照新生代、旧生代的方式来对对象进行收集,以尽可能的缩短GC对应用造成的暂停
      (1)对新生代的对象的收集称为minor GC,
      (2)对旧生代的对象的收集称为Full GC,
      (3)程序中主动调用System.gc()强制执行的GC为Full GC,
二、 JVM中自动内存回收机制
(1)引用计数收集器
 原理:
      引用计数是标识Heap中对象状态最明显的一种方法,引用计数的方法简单来说就是对每一个对象都提供一个关联的引用计数,以此来标识该对象是否被使用,当这个计数为零时,说明这个对象已经不再被使用了。

 优点:
      引用计数的好处是可以不用暂停应用,当计数变为零时,即可将此对象的内存空间回收,但它需要给每个对象附加一个关联引用计数

 缺点:
      并且引用计数无法解决循环引用的问题,因此JVM并没有采用引用计数。
(2)跟踪收集器
 原理:
      跟踪收集器的方法为停止应用的工作,然后开始跟踪对象,跟踪时从对象根开始沿着引用跟踪,直到检查完所有的对象。

根对象的来源主要有三种:
        1.被加载的类的常量池中的对象引用
        2.传到本地方法中,没有被本地方法“释放”的对象引用
        3.虚拟机运行时数据区中从垃圾收集器的堆中分配的部分

存在问题:
     跟踪收集器采用的均为扫描的方法,但JVM将Heap分为了新生代和旧生代,在进行minor GC时需要扫描是否有旧生代引用了新生代中的对象,但又不可能每次minor GC都扫描整个旧生代中的对象,因此JVM采用了一种称为卡片标记(Card Marking)的算法来避免这种现象。
(3)卡片标记算法
     卡片标记的算法为将旧生代以某个大小(例如512字节)进行划分,划分出来的每个区域称为卡片,JVM采用卡表维护卡的状态,每张卡片在卡表中占用一个字节的标识(有些JVM实现可能会不同),当Java代码执行过程中发现旧生代的对象引用或释放了对于新生代对象的引用时,就相应的修改卡表中卡的状态,每次Minor GC只需扫描卡表中标识为脏状态的卡中的对象即可

分享到:
评论

相关推荐

    【IT十八掌徐培成】Java基础第26天-01.回顾-JVM初步使用.zip

    本篇内容将深入探讨Java基础中的JVM初步使用,帮助你更好地理解Java程序在运行时的内部机制。 首先,我们需要了解JVM是什么。JVM是Java Virtual Machine的缩写,它是Java语言的一个关键组成部分,它是一个虚构的...

    QA:GCT Cukes-JVM 的初始 QA 沙箱

    "初始 QA 沙箱" 暗示这可能是一个用于初步测试和实验的环境,旨在安全地探索和验证 GCT 和 Cukes-JVM 的功能。 **描述解析:** "qa-bdd-gct GCT / Cukes-JVM 的初始 QA 沙箱" 描述进一步确认了这是 QA 和 BDD 的一...

    藏经阁-阿里巴巴Spark实践与探索 — 内存计算时代.pdf

    阿里巴巴的 Spark 历程可以分为三个阶段:初步尝试阶段(10-12 年),Spark on Yarn 阶段(12-14 年),内存计算阶段(14 年至今)。在这个过程中,阿里巴巴的 Spark 由 standalone 模式逐渐发展到 Yarn 模式,并...

    在CMT上如何对Java Application调优

    此外,还应探索如何更高效地利用CMT硬件特性。例如,可以通过调整应用程序的调度策略,让线程尽可能绑定到物理核心上,避免过多的上下文切换;或者优化数据布局,减少缓存不命中,提高数据访问速度。 ### 结论 在...

    Accp6.0 S2~Y2转换课程(Java方向)(完整课件九)

    5. JVM内部机制:初步探索Java虚拟机的工作原理,包括类加载、内存管理和垃圾收集等。 通过这些内容的学习,学员不仅能够提升Java编程技能,还能培养解决问题的能力,为成为专业的Java开发者奠定坚实基础。在实践中...

    Java入门+提高

    #### 一、Java开发环境和程序设计初步 ##### 1.1 Java语言发展历史 Java是由Sun Microsystems公司的James Gosling等人于1995年设计的一种面向对象的编程语言。最初的目标是为消费电子产品创建一种通用的编程语言和...

    java咖啡馆

    通过本文的介绍,我们初步了解了Java的基本概念、特点及其在实际中的应用。Java不仅是一种功能强大的编程语言,也是一个不断发展的生态系统。随着技术的进步,Java也在不断地进化和发展,为开发者提供了更多的可能性...

    Java深度历险.rar

    1. **JAVA2深度历险.jpg** - 这可能是一张封面图片,展示了本书的主题,即深入探索Java世界。它可能包含作者信息和书籍的主要内容概览,帮助读者对书的内容有一个初步的认识。 2. **CH_02.深入类别载入器.pdf** - ...

    java每月新闻杂志5

    1. **Java技术趋势**:2008年的Java技术趋势可能包括JVM优化、并发处理的提升以及云计算的初步探索。随着大数据和分布式计算的兴起,Java在这些领域的重要性逐渐凸显。 2. **框架与库**:可能会介绍当时的热门框架...

    MAT MemoryAnalyzer JDK8版本,亲测有用~!

    2. **导入到MAT**:在MAT中打开这个文件,工具会自动进行初步分析。 3. **分析结果**:查看"Leak Suspects"报告,寻找可能导致内存泄漏的对象或类。 4. **深度探索**:使用对象视图、引用链分析等功能进一步调查问题...

    Java准备知识(1)

    在深入探讨《Java准备知识(1)》这一主题时,我们首先要明确,Java是一种广泛...Java的学习之旅才刚刚开始,接下来,我们将继续探索更深入的主题,如数据结构、异常处理、线程管理等,以期成为一名合格的Java程序员。

    64位JDK 7.0

    模块化系统(Project Jigsaw)虽然未在JDK 7最终版中完全实现,但已开始初步探索。这个功能旨在改善Java平台的可维护性、安全性和性能,通过模块化的结构来组织代码。 在编译器方面,JDK 7引入了新的编译器优化,如...

    初步学习Java中线程的实现与生命周期

    了解这些基础知识后,你就可以开始探索更复杂的线程同步、通信机制,如`synchronized`关键字、`wait()`和`notify()`方法、`java.util.concurrent`包中的高级并发工具,以及线程池等高级主题。这些都是Java多线程编程...

    Java 第1章 了解java含源代码

    通过深入学习“Java 第1章 了解java含源代码”,你将建立起对Java编程的初步认识,并为后续章节的学习打下坚实的基础。记住,实践是检验真理的唯一标准,动手编写和运行代码是学习编程的关键。祝你在Java的世界里...

    Java Notes

    ### Java入门知识点详解 ...无论是对变量和数据类型的初步理解,还是对复杂控制结构和高级特性的深入探索,这份资料都能提供全面的帮助和支持。希望每位学习者都能够充分利用这份宝贵资源,不断提升自己的编程技能。

    java study

    "eda"可能指的是“数据探索性分析”(Exploratory Data Analysis),这是数据分析的初步阶段。在Java中,虽然不如Python或R常用,但仍有库如Weka和Deeplearning4j支持数据处理和分析。你可能需要了解如何读取和操作...

    mat内存分析工具win64.zip

    使用MAT时,首先需要获取heap dump文件,这通常可以通过JVM的命令行选项`-XX:+HeapDumpOnOutOfMemoryError`来设置,当出现OOM时自动生成。然后,通过MAT的`File` -&gt; `Open Heap Dump`菜单导入dump文件,进行分析。...

Global site tag (gtag.js) - Google Analytics