JVM(1)JVM介绍

  • JVM介绍
    • JVM是什么
    • JDKJREJVM之间的关系
    • 主流JVM有哪些
    • JVM内存模型
      • 程序计数器
      • 虚拟机栈
      • 本地方法栈
      • 堆区
      • 方法区
    • JVM内存划分

JVM介绍

JVM是什么?

JVM,java virtual machine,即java虚拟机,是运行java class文件的程序。java语言使用java虚拟机屏蔽了与平台相关的信息,使得java代码只需要进过编译,就可以运行在部署了JVM的平台上。java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这样就做到了“一次编译,到处运行”。
目前有scala、groovy等语言也能够生成class文件,这样不仅实现了平台的无关性,也实现了语言的无关性。

JDK、JRE、JVM之间的关系

可以理解为这三者是一个从大到小的关系。
JDK是程序开发者用来编译、调试java程序用的开发工具包。JDK中包含了很多工具供开发者使用,这些工具也是java程序,需要依赖JRE才能运行,因此在JDK的安装目录下有一个JRE目录,用于存放JRE文件。
JRE是java运行环境,所有的java程序都要在JRE上才能运行。
JVM是JRE的一部分,JRE包括JVM以及JVM运行时需要的类库。

主流JVM有哪些?

JVM有不同的实现,目前最主流的是Sun公司的HotSpot、IBM公司的J9 VM,我们一般讨论的是HotSpot。

JVM内存模型

JVM(1)JVM介绍_第1张图片

程序计数器

程序计数器是一块比较小的内存区域,用来记录当前线程执行到的字节码行号,每个线程都需要一个程序计数器用来记录执行哪些字节码,因此程序计数器是线程私有的。

虚拟机栈

每个线程都有一个虚拟机栈,栈是一个后进先出的数据模型。每个方法调用时,线程都要为该方法创建一个栈帧,即入栈;当方法执行完后,栈帧出栈。在线程中,只有虚拟机栈顶的栈帧是有效的,称为当前栈帧,该栈帧关联的方法称为当前方法。
虚拟机栈中存放了当前线程中局部基本类型的变量(java中的八种基本类型:boolean/byte/char/short/int/long/float/double)、部分返回结果、栈帧,非基本类型在虚拟机栈上只存放一个地址。

本地方法栈

本地方法栈在作用、运行机制、异常类型等方面都与虚拟机栈相同。唯一的区别:虚拟机栈是执行java方法的,本地方法是执行native方法的(native是与C/C++联合开发时使用的,使用native关键字说明这个方法是由C/C++实现的,并且被编译成dll,由java调用)。‘

堆区

在JVM所管理的内存区域中,堆区是最大的一块区域,也是JAVA GC的主战场。可以分为新生代和老年代。
堆区由所有线程共享,在虚拟机启动时创建。
堆区的存在的为了存储对象实例,绝大多数的对象在堆上分配内存。
堆区在实现上可以是固定大小的,也可以是可扩展的。目前主流的虚拟机是可扩展的。
如果执行垃圾回收后,堆区没有足够大小的内存,也不能进行扩展,就会报OutOfMemoryError:Java heap space异常。

方法区

方法区是各个内存共享的区域,用于存储全局变量、静态变量、final常量、类信息(包括版本、接口、方法等),也称为永久代。
方法区在物理上不要求是连续的,可以选择固定大小或者可扩展大小。
可以设置方法区是否被回收,回收的目标主要是常量池的回收和对类型的卸载。
当内存不足时,方法区会报OutOfMemoryError:PermGen space异常。

JVM内存划分

JVM(1)JVM介绍_第2张图片
young和tenured属于堆区。
young区被分为三个区域,eden区和两个大小严格相同的survivor,某一时刻只有一个survivor是使用的,另一个作为垃圾回收时复制对象使用。例如:eden区与survivor区的大小是32:1:1的关系,执行垃圾回收时,eden和一个survivor(a)空间一起做垃圾回收,将其中存活的对象复制到另一个survivor(b)中。然后清除eden和a的空间,再将eden和b一起用来存储对象,a留作下一次的垃圾回收。
在几次垃圾回收后,仍然存活的对象会被移到老年代中。移到老年代中的原因是新生代、老年代以及永久区的垃圾回收机制不一样,这个在后面的篇幅中会提到。
老年代用来存储新生代中经过几次垃圾回收仍然存活的对象,一般如果系统中用了application级别的缓存,缓存中的对象往往也会被转移到这一区间。
永久区就是方法区。
永久区主要放全局变量、静态变量、常量和类信息,如果放入很多这些信息也可能报OutOfMemoryError:PermGen space异常。一个例子是涉及到热部署的服务器时,重新部署后类的class没有被卸载掉,这样就导致了大量的class对象保存在永久区,重启就能解决问题。

你可能感兴趣的:(jvm,jvm)