• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

JVM概述

互联网 diligentman 3小时前 4次浏览

1、什么是JVM

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
Java虚拟机本质上就是一个程序,当它在命令行上启动的时候,就开始执行保存在某字节码文件中的指令。
Java语言的可移植性正是建立在Java虚拟机的基础上。任何平台只要装有针对于该平台的Java虚拟机,字节码文件(.class)就可以在该平台上运行。这就是“一次编译,多次运行”。

2、JDK、JRE和JVM关系

JVM概述

JDK = JRE + 开发工具(如编译器javac.exe)
JRE = JVM + 类库

JVM概述

Java程序的开发过程为:

    1、我们利用 JDK (调用 Java API)编写出 Java 源代码,存储于 .java 文件中
    2、JDK 中的编译器 javac 将 Java 源代码编译成 Java 字节码,存储于 .class 文件中
    3、JRE 加载、验证、执行 Java 字节码
    4、JVM 将字节码解析为机器码并映射到 CPU 指令集或 OS 的系统调用。

3、JVM的组成结构

JVM概述

JVM包含两个子系统和两个组件

两个子系统:

  • Class loader(类装载)
  • Execution engine(执行引擎)

两个组件:

  • Runtime data area(运行时数据区)
  • Native Interface(本地接口)

4、JVM运行时数据区

JVM概述

1、程序计数器(PC Register)

作用:记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值则为空。

异常:此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

2、虚拟机栈(JVM Stacks)

作用:是Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧用于存储数据。每一个方法从调用直至执行完成,对应栈帧在虚拟机栈中入栈到出栈的过程。

异常:会抛出StackOverflowError和OutOfMemoryErrror异常。

栈帧(Stack Frame)包含以下几个部分

1、局部变量表:是存放方法参数和局部变量的区域

2、操作栈:是个初始状态为空的桶式结构栈。在方法执行过程中,会有各种指令往栈中写入和提取信息。JVM的执行引擎式基于栈的执行引擎,其中的栈指的就是操作栈。i++和++i(字节码指令)

3、动态链接:每个栈帧中包含一个在常量池中对当前方法的引用,目的是支持方法调用过程的动态连接

4、方法返回地址:方法执行有两种退出情况,正常退出和异常退出,两者都将返回至方法当前被调用的位置。方法退出的过程相当于弹出当前栈帧

3、本地方法栈(Native Method Stacks)

作用:与虚拟机栈所发挥的作用非常相似,为虚拟机使用到的Native方法服务。线程开始调用本地方法时,会进入不再受JVM约束的世界。本地方法可以通过 JNI(Java Native Interface)来访问虚拟机运行时的数据区。

异常:会抛出StackOverFlowError和OutOfMemoryError异常。

4、方法区(Method Area)

作用:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

异常:当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。

垃圾回收:垃圾收集行为在这个区域时比较少出现的,其内存回收目标主要是对常量池的回收和对类型的卸载。JDK8之前,Hotspot中方法区的实现是永久代,JDK8开始使用元空间(Meta Space),以前永久代所有内容的字符串常量移至元空间,元空间直接在本地内存分配。

运行时常量池

1、是方法区的一部分

2、存放编译期生成的各种字面量和符号引用

3、Class文件中除了存有类的版本、字段、方法、接口等描述信息,还有一项是常量池,存有这个类的编译期生成的各种字面量和符合引用,这部分内容将在类加载后,存放到方法区的运行时常量池中

为什么废除1.7中永久代?

1、移除永久代是为融合Hotspot JVM与JR'ockit VM而做出的努力,因为JRockit没有永久代,不需要配置永久代

2、现实使用中,由于永久代内存经常不够用或发生内存泄露,爆出异常 java.lang.OutOfMemoryError: PermGen

3、基于此,将永久区废弃,而改用元空间,改为了使用本地内存空间

5、堆(Heap)

作用:Java虚拟机所管理的内存中最大的一块。Java堆是被线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。

异常:如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。

6、直接内存(Direct Memory)

直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是 Java 虚拟机规范中定义的内存区域。

在 JDK 1.4 中新加入了 NIO,引入了一种基于通道(Channel)与缓冲区(Buffer)的 I/O 方式,它可以使用 Native 函数库直接分配堆外内存,然后通过一个存储在 Java 堆中的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在 Java 堆和 Native 堆中来回复制数据。

程序计数器、虚拟机栈、本地方法栈是线程私有的,方法区、堆是线程共享的

 


程序员灯塔
转载请注明原文链接:JVM概述
喜欢 (0)