带你全面了解Jvm原理GC回收
什么是Jvm
JVM是Java虚拟机。它是由一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域组成。 JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行,由于不同系统都有对应相同版本的Java虚拟机,各自系统的虚拟机都可以识别并编译自己的字节码文件,这也就实现了Java的跨平台这一大特性。
JRE/JDK/JVM的关系
-
JRE称为Java运行环境。这就表明了,所有的Java程序都要在有JRE的情况下才能运行。
-
JDK称为Java开发环境。是程序开发者用来编译、调试java程序用的开发工具包。JDK的工具也是Java程序,也需要JRE才能运行。为了保持JDK的独立性和完整性,在JDK的安装过程中,JRE也是 安装的一部分。所以,在JDK的安装目录下有一个名为jre的目录,用于存放JRE文件。
-
JVM是JRE的一部分。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关,实现跨平台。
JVM原理
Jvm是Java的核心和基础,在Java编译器和Os平台之间的虚拟处理器。它是利用软件方法实现的抽象的计算机基于下层的操作系统和硬件平台,可以在上面执行Java的字节码程序。
Jvm的体系结构
- 类装载器:用来装载.class文件
- 执行引擎:执行字节码,或者本地方法
- 运行时数据区:内存空间中的方法区,堆,Java栈,Pc寄存器和本地方法栈。
- 方法区:称为“永久代”,“非堆”,用于存储虚拟机加载的类信息,常量,静态变量,是各个线程共享的区域,是*
线程共享
*的 - 运行时常量池:方法区的一部分,Class文件中除了有类的版本,字段,方法,接口等描述信息外,还有一项信息就是常量池,用于存放编译器生成的各种符号引用,这部分内容将在类加载后放到方法区的运行时常量池中。
- 虚拟机栈:当每个方法被执行的时候,都会创建一个栈用于存储局部变量,参数,操作栈,方法出口等信息。每个方法被调用到执行完成的过程,就对应着一个栈在虚拟机中从入栈到出栈的过程。生命周期和线程相同,是*
线程私有
*的 - 本地方法栈:与虚拟机栈基本类似,是为本地方法服务的,是*
线程私有
*的 - 堆:又称为GC堆,是JVM内存模块中最大的一块内存区域,是线程共享的,在Jvm启动时创建。存放了所有的实例对象以及数组值,既所有刚new的对象都在堆里。由于堆
是线程共享
的,因此在进行对象内存的分配的时候都要进行加锁,这也就导致了new对象的开销是比较大的 - 程序计数器:这是内存区域中最小的一块内存,他的作用是当前线程所执行的字节码的行号指示器,在虚拟机的模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支,循环,异常处理,线程恢复等基础功能都需要依赖计数器完成,是*
线程私有
*的。
对象是否存活的判定算法
由于方法区和堆是线程共享的,并不像虚拟机栈,程序计数器和本地方法栈是线程私有的。所以方法区和堆可以和GC回收扯上关系。
由于在堆中存在在所有的对象,所以在Gc回收之前都要考虑,哪些对象还活着,哪些对象已经死了,活着就让他继续活着,死了就让回收他。这时候就存在了某些算法来通过判断对象的存活状态从而判断是否该被回收。
1. 引用计数算法
给对象中添加一个引用计数器,每当一个地方应用了对象,计数器就加一;当引用失效的时候,计数器就减一;通过这样的加加减减,当计数器变为0的时候就表示该对象已死,可以进行回收操作。
- 缺点:很难解决两个对象之间相互循环引用的情况
2. 可达性分析算法
通过一系列称为“GC Roots"的对象作为起点,从这些节点开始向下搜索,搜索所走过的路劲称为引用链,当一个对象到 GC Roots没有与任何引用链相连&#x