java基础笔记(一)之JVM

1.JVM概述

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

JVM位置
如图所示:(JVM与硬件没有直接交互)java基础笔记(一)之JVM

2.JVM工作机制

JVM工作流程

如图所示:红色代表非常重要
java基础笔记(一)之JVM
大致可以这样理解:
(1)java的字节码文件通过类加载器进行装载。
(2)类加载器通过双亲委派机制找到相应的装载器将代码的各种信息存入内存空间。
(3)执行引擎访问内存空间并执行程序。
类装载器
类装载器负责将java字节码文件装载进内存,一般来说有四种类装载器。(1)启动类加载器(Bootstrap),用C++语言编写。
(2)扩展类加载器(Extension)。
(3)应用程序类加载器(App)。
(4)用户自定义类加载器。
类加载器遵循双亲委派机制,即优先寻找BootStrap,再Extension,然后App,最后自定义类加载器。(所以自定义的类不要与前面的类冲突,否则自定义的无效,根本不会被使用)
程序计数器
虚拟机执行字节码文件的地址,方便判断当前执行进程。
本地方法栈,本地方法接口,本地方法区
为了能够兼容C,C++程序代码,设置的区域,现在使用的不多。

2.JVM内存分析

(1)栈
栈内存主管Java程序的运行,每次线程创建都会创建,线程结束随即释放。栈是没有垃圾的,栈内存归为线程私有。栈内存主要存储三种变量:
1.本地变量(输入输出参数,方法内创建的变量)
2.栈操作(记录入栈,出栈)
3.栈帧数据(类文件,方法)
(2)方法区
方法区是存放许多线程共享资源的区域,一般来说,有以下数据:
1.静态变量
2.常量
3.类的构造方法
4.接口
5.字段与方法字节码
注意:一些线程私有的变量与方法不能存于方法区,应该存放到堆或栈中。
(3)堆
堆也是线程共享的区域。一般来说,堆主要存放类、方法、常变量,保存所有引用类型的数据。类也是GC机制的主要作用区。
堆内存分区如下图(前版本的元空间是永久区)
java基础笔记(一)之JVM

3.GC机制

堆内存中的GC
(1)所有的对象都是在Eiden区被new创建。
(2)发现Eiden区的空间满了,又需要创建新对象。在Eiden区进行Minor GC,所有剩余对象移入S0区。
(3)S0区域满了,对S0区域进行Minor GC,将剩余对象移入S1区。
(4)S1区域满了,对S1区域进行Minor GC,将剩余对象移入养老区Old。
(5)养老区满了,对养老区进行Major GC。
(6)进行Major GC后养老区仍然满了,出现java.lang.OutOfMemoryError: Java heap space异常,说明Java虚拟机的堆内存不够。原因有二:1.
Java虚拟机的堆内存设置不够,可以通过参数-Xms、-Xmx来调整。2.
代码中创建了大量大对象,并且长时间不能被垃圾收集器收集(存在被引用)。

GC四大算法
(1)引用计数算法
原理:一个对象如果没有任何与之关联的引用, 即他们的引用计数都不为 0, 则说明对象不太可能再被用到,那么这个对象就是可回收对象。
优缺点:引用计数收集器可以很快的执行,但是无法检测出循环引用。
用途:现在以及很少使用。
(2)复制算法
原理:按内存容量将内存划分为等大小的两块。每次只使用其中一块,当这一块内存满后将尚存活的对象复制到另一块上去,把已使用的内存清掉。
优缺点:简单且效率高,但是浪费内存空间。
用途:新生代的Minor GC。
(3)标记清除算法
原理:最基础的垃圾回收算法,分为两个阶段,标注和清除。标记阶段标记出所有需要回收的对象,清除阶段回收被标记的对象所占用的空间。
优缺点:内存碎片化严重,后续可能发生大对象不能找到可利用空间的问题。
用途:老年代的Major GC。
(4)标记压缩算法
原理:标记阶段和前算法相同, 标记后不是清理对象,而是将存活对象移向内存的一端。然后清除端边界外的对象。
优缺点:解决碎片化的问题,但需再遍历一次。
用途:老年代的Major GC。