【JVM】JVM快速入门(4)
前言:
本文内容:GC简介及回收机制、GC-复制算法、GC-标记压缩清除算法、GC算法总结
推荐免费JVM快速入门视频:【狂神说Java】JVM快速入门篇_哔哩哔哩_bilibili
JVM笔记代码下载地址:
蓝奏云:下载地址 密码:joker
百度云:下载地址 提取码:5xow
GC简介及回收机制
简介
Java GC(Garbage Collec,垃圾收集、回收),垃圾回收站,是将Java中无用的堆对象进行清理,释放内存空间,以免发生内存泄露。
JVM在进行GC时,并不是对这三个区域统一回收。大部分时候,回收都是新生代
- 新生代
- 幸存区(from to)
- 老年区
GC两种类型:轻GC(普通GC)、重GC(全局GC)
引用计数法
JDK1.1之后已经废弃
引用计数器算法是给每个对象设置一个计数器,当有地方引用这个对象的时候,计数器+1,当引用失效的时候,计数器-1,当计数器为 0 的时候,JVM就认为该对象不再被使用,视为 " 垃圾 "
存在的问题:
- 不能解决循环引用问题(例如A和B对象互相调用,无法被使用该算法的GC回收,导致内存泄漏)
- 每次计数器的增加和减少都带来了很多额外的开销
根搜索算法
GC Roots Tracing
根搜索算法是通过一些 GC Roots
对象作为起点,从这些节点开始往下搜索,搜索通过的路径成为引用链(Reference Chain),当一个对象没有被 GC Roots
的引用链连接的时候,说明这个对象是不可用的。
GC Roots对象:
- 虚拟机栈中的引用对象
- 方法区域中常量引用的对象
- 方法区域中的类静态属性引用的对象
- 本地方法栈JNI(native方法)引用的对象
GC-复制算法
复制算法是把内存分成大小相等的两块,每次使用其中一块,当GC(垃圾回收)的时候,把存活的对象复制到另一块上,然后把这块内存整个清理掉,并交换两块内存的角色,完成一次垃圾回收。
优点:
- 没有内存的碎片
缺点:
- 不适用于存活对象较多的内存,复制的时候会有较多的时间消耗
- GC过程中会将系统内存空间折半(会有一般的内存浪费)
GC-标记压缩清除算法
标记清除
标记—清除 算法包括两个阶段:标记和清除。
标记阶段,确定所有要回收的对象(即:未被标记的对象),并做标记;
清除阶段紧随标记阶段,将标记阶段确定不可用的对象清除;
缺点:
- 两个过程的效率都不高
- 清除之后会产生大量不连续的内存,效率比连续内存空间低
标记压缩
标记—压缩 把所有存活的对象压缩到内存的一端(即:把存活对象往内存的一端移动),然后直接回收边界以外的内存,并且回收完之后的内存空间是连续的。
缺点:
- 压缩阶段占用了系统的消耗,如果标记对象过多的话,损耗可能会很大
GC算法总结
算法总结
内存效率
复制算法>标记清除算法>标记压缩算法
内存整齐度
复制算法=标记压缩算法>标记清除算法
内存利用率
标记压缩算法=标记清除算法>复制算法
没有最好的算法,只有最合适的算法
GC:分代收集算法
年轻代:
- 存活率低
- 复制算法
老年代:
- 区域大,存活率高
- 标记清除算法(内存碎片不多)+标记压缩算法
拓展
JMM
-
什么是JMM?
JMM(Java Memory Model) Java内存模型
-
JMM的作用?
作用:缓存一致性协议,用于定义数据读写的规则
JMM定义了线程工作内存和主内存(Main Memory)之间的关系;线程之间的共享变量存储在主内存的,每个线程都有一个私有的本地内存(Local Memory)
解决共享对象可见性的问题:volilate
-
JMM的规则?
- 不允许read和load、store和write操作之一单独出现
- 不允许一个线程丢弃它的最近assign的操作,即变量在工作内存中改变了之后必须同步到主内存中。
- 不允许一个线程无原因地(没有发生过任何assign操作)把数据从工作内存同步回主内存中。
- 一个新的变量只能在主内存中诞生,不允许在工作内存中直接使用一个未被初始化(load或assign)的变量。即就是对一个变量实施use和store操作之前,必须先执行过了assign和load操作。
- 一个变量在同一时刻只允许一条线程对其进行lock操作,但lock操作可以被同一条线程重复执行多次,多次执行lock后,只有执行相同次数的unlock操作,变量才会被解锁。lock和unlock必须成对出现
- 如果对一个变量执行lock操作,将会清空工作内存中此变量的值,在执行引擎使用这个变量前需要重新执行load或assign操作初始化变量的值
- 如果一个变量事先没有被lock操作锁定,则不允许对它执行unlock操作;也不允许去unlock一个被其他线程锁定的变量。
- 对一个变量执行unlock操作之前,必须先把此变量同步到主内存中(执行store和write操作)。