转自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需要用到的东西。而这个运行时数据区里面又会分为许多的小区。每个区都有自己不同的职责。后面会讲到每个区的作用和存储的内容。

三: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中的内存区域。如下图: 



                                                          

注意: 存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运行机制的更多相关文章

  1. JVM学习001通过实例总结Java虚拟机的运行机制

    JVM学习(1)——通过实例总结Java虚拟机的运行机制-转载http://www.cnblogs.com/kubixuesheng/p/5199200.html 文章转载自:http://www.c ...

  2. JVM学习(1)——通过实例总结Java虚拟机的运行机制

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: JVM的历史 JVM的运行流程简介 JVM的组成(基于 Java 7) JVM调优参数:-Xmx和-Xms ...

  3. JVM学习(1)——通过实例总结Java虚拟机的运行机制(转)

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: JVM的历史 JVM的运行流程简介 JVM的组成(基于 Java 7) JVM调优参数:-Xmx和-Xms ...

  4. JVM学习(1)——通过实例总结Java虚拟机的运行机制-转载http://www.cnblogs.com/kubixuesheng/p/5199200.html

    JVM系类的文章全部转载自:http://www.cnblogs.com/kubixuesheng/p/5199200.html 特别在此声明.那位博主写的真的很好 ,感谢!! 俗话说,自己写的代码, ...

  5. 深入理解Java虚拟机-JVM运行时数据区域

    一.运行时数据区域 1.程序计数器 程序计数器( Program Counter Register) 是一块较小的内存空间, 它可以看作是当前线程所执行的字节码的行号指示器. Java虚拟机的多线程是 ...

  6. Java虚拟机JVM学习07 类的卸载机制

    Java虚拟机JVM学习07 类的卸载机制 类的生命周期 当Sample类被加载.连接和初始化后,它的生命周期就开始了. 当代表Sample类的Class对象不再被引用,即不可触及时,Class对象就 ...

  7. Java虚拟机JVM学习05 类加载器的父委托机制

    Java虚拟机JVM学习05 类加载器的父委托机制 类加载器 类加载器用来把类加载到Java虚拟机中. 类加载器的类型 有两种类型的类加载器: 1.JVM自带的加载器: 根类加载器(Bootstrap ...

  8. Java虚拟机JVM学习03 连接过程:验证、准备、解析

    Java虚拟机JVM学习03 连接过程:验证.准备.解析 类被加载后,就进入连接阶段. 连接就是将已经读入到内存的类的二进制数据合并到虚拟机的运行时环境中去. 连接阶段三个步骤:验证.准备和解析. 类 ...

  9. Java Jvm运行机制原理

    一:简介 在学习Java虚拟机之前,也就是Jvm之前,我想大家能够带着问题去学习,这样的话,大家学习起来也会比较有所获! 1.Java虚拟机(Jvm)是什么? 2.Java虚拟机是用来干什么的? 3. ...

随机推荐

  1. apktool重打包签名后安装出现“Failure [INSTALL_FAILED_ALREADY_EXISTS]”

    一般修改.签名环节不出错的话,可以考虑看是不是包名重复的问题,如果系统中存在相同包名的应用,安装时会报这个错误 就算apk名字变了,但和原来的包名仍是一样的,所以先卸载掉系统里同包名的应用,再尝试安装 ...

  2. [转]ORACLE 绑定变量用法总结

    转:http://blog.csdn.net/wanghai__/article/details/4778343 在oracle 中,对于一个提交的sql语句,存在两种可选的解析过程, 一种叫做硬解析 ...

  3. PAT L1-009. N个数求和

    本题的要求很简单,就是求N个数字的和.麻烦的是,这些数字是以有理数“分子/分母”的形式给出的,你输出的和也必须是有理数的形式. 输入格式: 输入第一行给出一个正整数N(<=100).随后一行按格 ...

  4. WCF学习系列二_使用IIS发布WCF服务

    原创作者:灰灰虫的家http://hi.baidu.com/grayworm 上一篇中,我们创建了一个简单的WCF服务,在测试的时候,我们使用VS2008自带的WCFSVCHost(WCF服务主机)发 ...

  5. JAVA长连接demo

    http://blog.csdn.net/caomiao2006/article/details/38830475 JAVA长连接demo 2014-08-25 23:20 4767人阅读 评论(2) ...

  6. Java中到底有没有指针;同时注意引用和指针的区别

    Java中引用的作用类似于指针,但是有区别:()    (1) 指针必然指向一个内存地址,如果你定义的时候不指定,就会乱指(很可能造成安全隐患)但是引用定义出来后默认指向为空.     (2) 指针可 ...

  7. onMouseDown onMouseUp onMouseMove(移动鼠标图像大小变化)

  8. 抓取Bing每日图片作为网站首页背景

    把Bing搜索的背景图片设置为自己网站的背景,实现背景及资讯的每日更新 效果图如下: 理一下思路,首先我们要抓取Bing的每日图片及最新资讯,然后保存图片及信息到本地,最后显示图片及资讯到网站首页. ...

  9. Xcode6.1模拟器ios8.1模拟器不能弹出虚拟键盘及虚拟键盘无法切换中文输入的解决办法

    1.不能弹出虚拟键盘的解决办法 模拟器菜单Hardware->Keyboard->Connect Hardware Keyboard取消选中,快捷键commad+shift+K 2.虚拟键 ...

  10. java新手笔记3 运算符&循环

    1.包 2.运算符 public class Operator { public static void main(String[] args) { int a = 5; System.out.pri ...