一、Java 虚拟机的概念
所谓虚拟机,就是一台虚拟的机器,它是一款软件,用来执行一系列虚拟计算机指令。大体上虚拟机可以分为系统虚拟机和程序虚拟机。Virtual Box、VMWare 就属于系统虚拟机,它们完全是对物理计算机的仿真,提供了一个可运行完整操作系统的软件平台。程序虚拟机的典型代表就是 Java 虚拟机,它专门为执行单个计算机程序而设计,在 Java 虚拟机中执行的指令我们称为 Java 字节码指令。
二、Java 虚拟机的结构
-
类加载子系统
负责从文件系统或者网络中加载 Class 信息,加载的信息存放在一块称之为方法区的内存空间。 -
方法区
存放类信息、常量信息、常量池信息,包括字符串字面量和数字常量等。 -
Java 堆
在 Java 虚拟机启动的时候建立 Java 堆,它是 Java 程序最主要的内存工作区域,几乎所有的对象实例都存放到 Java 堆中,堆空间是所有线程共享。 -
直接内存
Java 的 NIO 库允许 Java 程序使用直接内存,从而提高性能,通常直接内存的速度会优于 Java 堆,读写频繁的场合可能会考虑使用。 -
Java 栈
每个虚拟机线程都有一个私有的栈,一个线程的 Java 栈在线程创建的时候被创建,Java 栈中保存着局部变量,方法参数,方法调用、返回值等。 -
本地方法栈
本地方法栈与 Java 栈非常类似,最大不同是,本地方法栈用于本地方法调用,Java 虚拟机运行 Java 直接调用本地方法(通常使用 C 编写)。 -
垃圾收集系统
-
PC(Program Counter) 寄存器
PC 寄存器也是每个线程私有的空间,Java 虚拟机会为每个线程创建 PC 寄存器。在任意时刻,一个 Java 线程总在执行一个方法,这个方法被称为当前方法,如果当前方法不是本地方法,PC 寄存器就会执行当前正在被执行的指令;如果是本地方法,则 PC 寄存器值为 undefined。寄存器存放如当前执行环境指针,程序计数器,操作栈指针,计算的变量指针等信息。 -
执行引擎
虚拟机最核心的组件就是执行引擎了,它负责执行虚拟机的字节码。
堆、栈、方法区的区别与联系:
堆解决的是数据存储的问题,即数据怎么放,放在哪儿。
栈解决的是程序运行的问题,即程序如何运行,或者说如何处理数据。
方法区则是辅助堆栈的快永久区(Perm),解决堆栈信息的产生,是先决条件。
例如,我们创建一个新的对象 User。那么,User 类的一些信息(类信息、静态信息都存在于方法区中);而 User 对象被实例化出来以后,被存储到 Java 堆中,一块内存空间;当我们去使用的时候,都是使用 User 对象引用,形如 User user = new User() 这里的 user 就是存放在 Java 栈中的,即 User 真实对象的一个引用。
根据垃圾回收机制的不同,Java 堆有可能拥有不同的结构。最为常见的就是将整个 Java 堆分为新生代和老年代。其中新生代存放新生的或者年龄不大的对象,老年代则存放老年对象。新生代分为 Eden 区、s0 区、s1 区,s0 区、s1 区是两块大小相等且可以互换角色的空间。
Java 栈一块线程私有的内存空间,栈一般由三部分组成:局部变量表、操作数栈和帧数据区。
Java 方法区和堆一样,是一块所有线程共享的内存区域,它保存系统的类信息,比如类的字段、方法、常量池等。方法区的大小决定了系统可以保存多少个类,如果系统定义太多的类,会导致方法区溢出,虚拟机也会抛出内存溢出错误。方法区可以理解为永久区(Perm)。
三、JVM 参数
- 堆分配参数
-XX:+UseSerialGC:配置串行回收期
-Xms:设置 Java 程序启动时初始堆大小
-Xmx:设置 Java 程序能获得的最大堆大小
-Xmn:设置新生代的大小。新生代大小一般会设置为整个堆空间的 1/3 到 1/4 左右。
-XX:SurvivorRatio:设置新生代中 Eden 区域和 s0/s1 区域的比例。
四、垃圾回收及其算法
-
引用计数算法
无法处理循环引用的情况,且每次进行加减操作比较浪费系统性能。 -
标记-清除算法
会产生空间碎片. -
复制算法
-
标记压缩算法
五、垃圾收集器
-
串行垃圾收集器
-
并行垃圾收集器
ParallelGC,吞吐量优先收集器 -
CMS 收集器
-
G1 收集器
网友评论