JVM的初步理解

Posted mlfz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM的初步理解相关的知识,希望对你有一定的参考价值。

一、jdk,jre,jvm

JRE:(Java Runtime Environment,Java运行环境),也就是Java平台。所有的Java 程序都要在JRE下才能运行。普通用户只需要运行已开发好的java程序,安装JRE即可。

JDK:(Java Development Kit)是程序开发者用来来编译、调试java程序用的开发工具包。JDK的工具也是Java程序,也需要JRE才能运行。为了保持JDK的独立性和完整性,在JDK的安装过程中,JRE也是安装的一部分。所以,在JDK的安装目录下有一个名为jre的目录,用于存放JRE文件。 

JVM:(Java Virtual Machine,Java虚拟机)是JRE的一部分。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关,实现跨平台。

技术图片

 

 

二、虚拟机的构成

技术图片

1、程序计数器:

  是一个小的内存空间,用来记录当前线程执行到哪一步操作。如果线程正在执行的是一个java方法,则此内存区域记录正在执行的虚拟机字节码指令的地址;如果线程正在执行的是native方法,则计算器中的值为空。此内存区域是唯一一个在JAVA虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

 

 

 

2、虚拟机栈:

  一般用来储存局部变量表、操作数表、动态链接等。每个线程方法在执行时都会创建一个栈帧,包含局部变量表、返回地址、操作数栈等信息。每个方法的执行与完成就对应的栈帧的入栈与出栈过程局部变量表占用空间的大小在编译期就确定了。这里需要注意:如果线程请求的栈深度大于虚拟机所允许的深度,将会抛出StackOverflowError异常;如果虚拟机栈可以动态扩展(当前大部分的Java虚拟机都可动态扩展,只不过Java虚拟机规范中也允许固定长度的虚拟机栈),当扩展时无法申请到足够的内存时将会抛出OutOfMemoryError异常。

3、本地方法栈:

这是另一个栈,用来提供虚拟机中用到的本地服务,像线程中的start方法,JUC包里经常使用的CAS等方法都是从这来的。

4、堆:

    是JVM中最大的一块内存区域,该区域的目的只是用于存储对象实例及数组。该区域也是GC的最主要区域。
        根据Java虚拟机规范的规定,Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可,就像我们的磁盘空间一样.在实现时,既可以实现固定大小的,也可以是可扩展的,不过当前主流的虚拟机都是按照可扩展来实现的(通过-Xmx和-Xms控制).如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,就会抛出OutOfMemoryError异常。

5、方法区:

   用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
        运行时常量池(Runtime Constant Pool)是方法区的一部分。.Class文件中除了有类的版本/字段/方法/接口等描述信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容将类在加载后进入方法区的运行时常量池中存放.

 

运行时常量区的内容并不只是在编译期间产生,通过String.intern()也可以实现在运行时向常量区中添加内容。

 

        需要注意的是:从JDK8开始,方法区被元数据区替代了。具体的原因和两者的区别可以参考官网。

 

6、常量池:

存放final修饰的成员变量、直接定义的字符串(如 Sring s = "test";这种)还有6种数据类型包装类型从-128~127对应的对象(这也解释了我们new两个在这区间的包装类型对象时,为什么他们是一样的,布尔类型存放的是true和false两种,浮点类型Double和Float因为精度问题不存入其中)等

 

以上是关于JVM的初步理解的主要内容,如果未能解决你的问题,请参考以下文章

JVM的初步理解

一文理解JVM的类加载系统

透彻理解JVM类加载子系统

jvm,深入理解java虚拟机,实战:OutOfMemoryError异常

jvm,深入理解java虚拟机,实战:OutOfMemoryError异常

jvm,深入理解java虚拟机,实战:OutOfMemoryError异常