JVM:Java Virtual Machine 是Java的虚拟机,是JRE的一部分。它是整个java实现跨平台的最核心的部分,负责解释执行字节码文件,是可运行java字节码文件的虚拟计算机,是一个位于Java与操作系统之间的中间态。有自己完善的硬件结构,如处理器、堆栈、寄存器等,还具有相应的指令系统。所有平台的上的JVM向编译器提供相同的接口,而编译器只需要面向虚拟机,生成虚拟机能识别的代码,然后由虚拟机来解释执行。
GC(garbage collection)是垃圾回收,它的主要作用就是回收程序中不再使用的内存. 在 C/C++等语言中, 由程序员负责回收无用内存。Java 语言消除了程序员回收无用内存空间的责任:
JVM 提供了一种系统线程跟踪存储空间的分配情况。 并在 JVM 的空闲时, 检查并释放那些可以被释放的存储空间。GC是在java程序运行过程中自动启用的,程序员无法精确控制和干预。
一.Java虚拟机(Java Virtual Machine )JVM
1.它有一个解释器组件,可以实现Java字节码和操作系统间的通信。
2.对于不同的运行平台,有不同的JVM
3.JVM屏蔽了底层运行平台的差别,实现了“一次编译,随处运行”
二.垃圾回收器(Garbage Collection)GC
1.不再使用的内存空间应当进行回收。如:
① 对象没有引用
②作用域发生未捕获异常
③程序在作用域正常执行完毕
④程序执行了System.exit()
⑤程序发生意外终止(被杀线程等
2.JVM提供了一个系统线程,用于追踪存储空间的分配情况,检查并释放那些可以被释放的存储空间(当需要执行GC时,除GC所需的线程外,所有的线程都进入等待状态,直到GC任务完成。这种操作被称为stop-the-world)
3.JVM GC只回收堆区和方法区内的对象。而栈区的数据,在超出作用域后会被JVM自动释放掉,所以其不在JVM GC的管理范围内。
4.垃圾回收器在Java程序运行过程中自动启用,程序员无法精确的控制和干预
JVM内部体系结构大致分为三部分:类装载器(ClassLoader)子系统,运行时数据区和执行引擎。
java程序运行与JVM的关系:
1.java源文件编译生成.class文件(字节码)
2.字节码由JVM解释运行。
因为java程序既要编译同时也要经过JVM的解释运行,所以java被称为半解释语言。
• 类装载器(ClassLoader)(用来装载.class文件)—— 使用双亲委派模型
• 堆是所有线程共享的,栈是每个线程独有一个,用于存储基本类型和对象的引用
• PC寄存器:存储每个线程下一步将执行的JVM指令
• 方法区:存储类的信息,包括属性、方法;存储于堆空间的perm区域
• 本地方法栈:存储native方法
可作为GC root的对象有以下几种:
一、虚拟机栈(栈帧中的本地变量表)中引用的对象。
二、方法区中类静态属性引用的对象。
三、方法区中常量引用的对象。
四、本地方法栈中引用的对象。
GC (Garbage Collection)的基本原理:
将内存中不再被使用的对象进行回收,GC中用于回收的方法称为收集器,由于GC需要消耗一些资源和时间,Java在对对象的生命周期特征进行分析后,按照新生代、旧生代的方式来对对象进行收集,以尽可能的缩短GC对应用造成的暂停
(1)对新生代的对象的收集称为minor GC;
(2)对旧生代的对象的收集称为Full GC;
(3)程序中主动调用System.gc()强制执行的GC为Full GC。
GC的回收机制:
1.分配内存
2.确保被引用对象的内存不被错误的回收
3.回收不再被引用的对象的内存空间
JVM工作原理
JVM在整个JDK中处于最底层,负责与操作系统的交互。操作系统装入jvm是通过JDK中的java.exe来实现的,具体步骤如下:
a、创建JVM装载环境和配置;
b、装载jvm.dll;
c、初始化jvm.dll;
d、调用JNIEnv实例装载并处理class类;
e、运行java程序
4、如何判断对象是否存活:
判断对象常规有两种方法:引用计数算法和可达性分析算法(Reachability Analysis)。
引用计数算法:给对象添加一个引用计数器,每当有一个地方引用它时计数器加1,引用释放时计数减1,当计数器为0时可以回收。
引用计数算法实现简单,判断高效,在微软COM和Python语言等被广泛使用,但在主流的Java虚拟机中没有使用该方法,主要是因为无法解决对象相互循环引用的问题。
可达性分析算法:基本思想是通过一系列称为“GC Root”的对象(如系统类加载器、栈中的对象、处于激活状态的线程等)作为起点,基于对象引用关系,开始向下搜索,所走过的路径称为引用链,当一个对象到GC Root没有任何引用链相连,证明对象是不可用的。
垃圾回收器如发现一个对象不能被任何活线程访问时,它将认为该对象符合删除条件,就将其加入回收队列,但不是立即销毁对象,何时销毁并释放内存是无法预知的。垃圾回收不能强制执行,然而Java提供了一些方法(如:System.gc()方法),允许你请求JVM执行垃圾回收,而不是要求,虚拟机会尽其所能满足请求,但是不能保证JVM从内存中删除所有不用的对象。