深入解析java虚拟机-jvm运行机制

转载 2015年11月17日 22:44:48
转自oschina


一:JVM基础概念

         JVM(Java虚拟机)一种用于计算设备的规范,可用不同的方式(软件或硬件)加以实现。编译虚拟机的指令集与编译微处理器的指令集非常类似。Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。 
         Java虚拟机(JVM)是可运行Java代码的假想计算机。只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任何Java代码能够在该系统上运行。

带着几个问题我们来阅读下面的文章,希望能够对jvm运行机制不是很清楚的朋友有一点点的帮助。如果对jvm运行机制非常了解可以留言 提下意见和你认为不对的地方。

  1. jvm是怎么运行的?
  2. jvm运行时内存是怎么分配的?
  3. jvm每个区在jvm体系中都充当着什么角色?
  4. java文件里面的代码最终都存储在jvm的那些区?

二:JVM体系结构

       Java虚拟机,java源文件(.java)通过编译器生成字节码文件(.class),字节码文件(.class)通过JVM(Java虚拟机)中的解释器再翻译成特定机器上的机器码。 
编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行。每一种平台的解释器是不同的,但是实现的虚拟机是相同的。当一个程序从开始运行一个程序,这时虚拟机就开始实例化了。多个程序启动就会存在多个虚拟机实例。程序退出或者关闭。则虚拟机实例消亡。多个虚拟机实例之间数据不能共享。

如下图所示,JVM的体系结构包含几个主要的子系统和内存区:

  1. 垃圾回收器(Garbage Collection):负责回收堆内存(Heap)中没有被使用的对象,即这些对象已经没有被引用了。
  2. 类装载子系统(Classloader Sub-System):除了要定位和导入二进制class文件外,还必须负责验证被导入类的正确性,为类变量分配并初始化内存,以及帮助解析符号引用。
  3. 执行引擎(Execution Engine):负责执行那些包含在被装载类的方法中的指令。
  4. 运行时数据区(Java Memory Allocation Area):又叫虚拟机内存或者Java内存,虚拟机运行时需要从整个计算机内存划分一块内存区域存储jvm需要用到的东西。而这个运行时数据区里面又会分为许多的小区。每个区都有自己不同的职责。后面会讲到每个区的作用和存储的内容。 

                      push_thumb[23]

三:jvm运行时数据区

  • 程序计数器 (Program Counter Register):

         是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实 现),字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

         由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间的计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。

         如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Natvie方法,这个计数器值则为空(Undefined)。此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

  • 栈 (stack):

        这块区域是线程私有的,它的生命周期和和线程一样。在jvm中。每个方法执行的时候jvm都会创建一个栈帧。用来存储局部变量、操作栈、动态栈和方法返回等信息。每一个方法从调用到结束对应着一个栈帧在虚拟机里面的入栈和出栈。

       栈里面存储了编译器已知的八种基本数据类型,String不在里面。后面会对String类型进行详细的介绍。(boolean、char、double、int、long、byte、float、short)。 
在用java关键字 new 一个对象时。比如(ControllerHelper helper = new ControllerHelper ())时。stack内存中存储的是一个helper栈帧地址引用。其地址指向的是heap中的内存区域。如下图: 

                                                          1_thumb[13]

注意: 存Heap地址引用只对于sun 公司的虚拟机<HotSpot>。其他公司的可能会不一样。存的可能是句柄。

  • 本地方法区 (Native Method Area)

       这块区域在jvm运行内存中职责就相对比较少了。只是执行Native 方法。如果这个区的内存不足也是会抛出StackOverflowError 和 OutOfMemoryError 异常。
  • 堆 (Heap)

        这块区域可以说是jvm中最大的一块区域了。几乎所有的对象和数据都是存在这个区域。这块区域也是线程共享的。也是 gc 主要的回收区。可以从我第一个图看出Heap区中还可以分为新生代(Young Generation)和老年代(Old Generation)。gc每隔一段时间就会对新生代进行垃圾回收。在分配对象遇到内存不足时,先对新生代进行GC(Young GC);当新生代GC之后仍无法满足内存空间分配需求时, 才会对整个堆空间以及方法区进行GC(Full GC)。而新生代又可以分为一个Eden空间和两个Survivor (From Survivor 和 To Survivor ) 空间。新生代中的E区和S区又有不同的职责。 
       E区:gc 触发比较频繁的区域。存储的是新new的对象。几乎所有的对象都会经过E区。如果gc过后对象还没死亡就会把未死亡的对象存储到S区。 
       S区:Survivor 区作为Eden区和old(老年代)的缓存。它是可以向老年代转移活动对象的实例。

java 堆它在屋里内存上可以是不连续的内存空间。只要是逻辑上是连续的就可以了。查看程序新生代、老年代信息可以执行命令 jstat -gcutil 6912 500

  • 方法区 (Method Area)

       方法区和堆一样也是线程共享的区域,它主要是存储被虚拟机加载的类信息、常量、静态变量、及时编译器编译后的代码等数据。它不属于Heap区域中的一部分。对于sun公司的HotSpot虚拟机来说。gc也会对这块区域进行垃圾回收。但是对于heap的垃圾回收而已。这块区域垃圾回收比较少。String str=”is string”。str就是存在方法区。Sample.class.getSimpleName() 方法就是从方法区中区得的结果。

        如果细分方法区还可以细分为运行常量池 (Runtime Constant Pool) 。它主要存储class文件中的版本、字段、方法、接口等描述信息。运行常量池还可以分为信息常量池 (Constant Pool Table)。它主要是存储编译器生成的各种字面量和符号引用。

       并不是所有的常量都只能在编译期产生。对于String类型的 intern( )方法就可以在运行时把变量存入方法区。当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。

相关文章推荐

深入解析java虚拟机-jvm运行机制

JVM体系结构 Java虚拟机,java源文件(.java)通过编译器生成字节码文件(.class),字节码文件(.class)通过JVM(Java虚拟机)中的解释器再翻译成特定机器上...

java虚拟机运行机制

首先简单阐述下解释型语言和编译型语言的联系与区别。 编译型语言是通过编译器讲程序编译成目标机器所能识别的机器码,而解释型语言不需要编译过程。由该语言的解释器读取脚本,按照语言规则进行解释,然后调用解释...

从java虚拟机底层理解java语言运行机制 001

类的加载、连接、初始化 一、先来讲讲java虚拟机和程序的生命周期: 在如下几种情况Java虚拟机会结束生命周期: —执行System.exita() 方法 —程序正常之行结束 —程序在执行过程...

深入理解ART虚拟机—ART的函数运行机制

前面两篇文章介绍了ART的启动过程,而在启动之后,我们感兴趣的就是ART是怎么运行的。回顾一下虚拟机系列的前面几篇文章,我们可以理一下思路: 一,apk以进程的形式运行,进程的创建是由zygote。 ...

深入理解Java虚拟机(一)-jvm运行时数据区

前言对于Java程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要为每一个new操作去写对应的delete/free代码,不容易出现内存泄漏和内存溢出问题,由虚拟机管理内存。不过,也正是Java程...
  • FX_SKY
  • FX_SKY
  • 2016-04-30 23:16
  • 1474

《深入理解Java虚拟机——JVM高级特性与最佳实践》学习笔记——晚期(运行期)优化

晚期(运行期)优化概述在部分的商用虚拟机(Sun HotSpot、IBM J9)中,Java程序最初是通过解释器进行解释执行的,当虚拟机发现某个方法或代码块的运行特别频繁时,就会把这些代码认定为”热点...

JVM内存管理机制----对《深入理解JAVA虚拟机》第二章的理解(上)

JVM内存区域分为五块:虚拟机栈,本地方法栈,程序计数器,堆区,方法区。 虚拟机栈(线程私有):执行java方法,线程中每执行一个方法都会创建一个栈帧。方法调用时,栈帧在JVM中入栈,方法结束时,出栈...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)