大家好,又见面了,我是你们的朋友全栈君。
JVM垃圾回收机制
提到Java垃圾回收机制就不得不提到一个方法:
system.gc() 用于调用垃圾收集器,在调用时垃圾收集器将运行以回收未使用的内存空间,它将尝试释放被丢弃对象所占用的空间。
作为程序员有必要了解gc方法,这也是在面试中经常会被问及的问题:
我们从三个方面来理解gc:
1.JVM如何确定哪些空间能被回收?
2.JVM会在什么时候进行垃圾清除的动作?
3.JVM如何清除垃圾的?
1.JVM如何确定哪些空间能被回收
通过两个算法:
引用计数算法:
可达性分析算法:
2.JVM会在什么时候进行垃圾清除的动作
- 会在cpu空闲的时候自动进行回收
- 在堆内存存储满了之后
- 主动调用System.gc()后尝试进行回收(不一定成功)
3.JVM如何清除垃圾的?
通过四个算法:
- 标记-清除算法:
先 标记 所有需要回收的对象,然后 清除 标记的对象
缺点:会产生 空间碎片 ,资源浪费
- 复制算法
将 内存分为两块 ,当使用的一块满了就将 存活对象 复制到另一块中,再将使用的那一块清空
缺点:内存缩小约为原来的一半
- 标记-整理算法
先 标记 所有需要回收的对象,然后 清除 标记的对象,再将剩下的 存活对象整理 ,避免了空间碎片的产生
- 分代收集算法
分代收集算法是比较智能的垃圾回收算法,也是现在JVM使用最多的算法,他本身其实并不算是一种算法,而是会在具体的场景上选择上面三种方法来进行垃圾回收
“代”指的是 新生代、老年代、永久代
【新生代】
按8:1:1分为 eden、survivorl0、survivor1 三个区域
一般情况下所有新生成的对象都存放于新生代
在新生代中,每次垃圾收集时都发现有 大批对象死去 ,只有少量存活,那就选用复制算法。只需要付出少量 存活对象 的复制成本就可以完成收集。
【老年代】
老年代中存放的一般都是生存周期比较长的对象
老年代中因为 对象存活率高 、没有额外空间对他进行分配担保,就必须用标记 – 清除或者标记 – 整理
【永久代】
主要用来存放静态文件
【注意】在jdk8的时候Java废弃了永久代,同时提供了与永久代类似的叫做“元空间”的技术。元空间的本质和永久代类似。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。也就是不局限于 jvm 可以使用系统的内存。理论上取决于 32 位 / 64 位系统可虚拟的内存大小。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/136666.html原文链接:https://javaforall.cn