java基础

垃圾回收

2018-08-16  本文已影响8人  低调_0c1d

背景

与C++对比,C++的内存回收是有C++的代码控制的,而JAVA的内存回收是由JVM的垃圾回收器控制的,看起来JAVA的垃圾回收更“自动化”,但是当需要排查内存溢出和内存泄漏问题时,垃圾回收器成为系统的瓶颈,此时就需要对这些“自动化”的技术实施监控和调节。

GC的区域

jvm的运行时数据区主要分为方法区、堆、虚拟机栈、本地方法栈、程序计数器。
其中,虚拟机栈、本地方法栈、程序计数器是线程私有的,一旦线程执行完成,内存就会自然回收。
方法区、堆是线程共用的,不会随着线程结束而回收,所以GC主要是针对方法区和堆。

GC的的目标对象

决定对象的内存空间是否需要被回收,主要由两种方式引用计数和可达性分析

引用计数

引用计数的方式可以简单高效的实现,但是因为存在缺陷(一旦出现循环引用则永远不能被回收),所以没有的jvm的GC中是用,

可达性分析

可达性分析是指从GC ROOTS出发,根据依赖关系是否可以达到指定的对象,如果可达,则对象不能被回收,如果不可能,则对象可以被回收。
另外,除了强引用外,还有软引用、弱引用、虚引用等,主要一次随着应用强度而减弱,而在空间回收时,按照相反次序进行内存回收。

GC roots的对象主要扩一下四种:

GC的算法

垃圾回收的算法主要包括四种:

标记-清除

一次标记,一次请求,缺点是回收效率低,并且造成大量的内存碎片,虽然有诸多缺点但是却是其他后续的算法的基础

标记-复制

将空间分成相等的两部分,每次只使用一块,虽然效率提高,但是也造成了大量的空间浪费

标记-整理

在“标记-清除”的基础上,对剩余的空间进行碎片整理,这样提高了空间的使用率,降低了下次分配内存空间因为连续空间不足而导致需要再次GC的问题

分带收集算法

根据对象的生命周期特性,90%以上新生对象是很快就要被回收的,所以整体上将内存空间分为新生代和老年代,并且将新生代分为Eden和两个相等的Survivor区。新生对象分配的空间在Eden和一个survivor中,每次minor GC后,将存货的对象负责到另一个survivor上。
默认参数-XX:SurvivorRatio=8
Eden:s0:s1=8:1:1

GC的类型

GC的日志

上一篇 下一篇

猜你喜欢

热点阅读