JAVA(GC)线程的生命

1.什么是垃圾?

垃圾是指在运行程序中没有任何指针指向的对象,这个对象就是需要被回收的垃 圾。java虚拟机中的空间并不是无限大,所以当垃圾存在一段时间时,虚拟机就会自行将垃圾进行清理,如果清理不及时或者主动取消清理,那么就会造成内存溢出.

2,什么GC,为什么需要GC?

1,对于高级语言;来说内存空间需要不断的更新,才能使程序保持活力,同时垃圾回收也可以清除内存里的记录碎片。碎片整理 将所占用的堆内存移到堆的一端,以便 JVM 将整理出的内存分配给新的对象。随着程序的大小逐渐增加,没有GC程序的基本运行就会出现问题.

3.java的垃圾回收机制.

3.1自动内存管理

字面意思自动内存管理无需开发人员手动参与内存的分配与回收,这样可以减低内存泄漏与内存溢出的风险,同时减少了由于开发人员的不当操作所造成的风险,可以使开发人员更专心于业务开发.

3.2自动内存管理的问题

最直接问题:弱化 Java 开发人员在程序出 现内存溢出时定位问题和解决问题的能力,即使用自动内存管理仍需了解自动内存分配与内存回收管理,当自动内存管理出现问题时,我们便可以对这一方法实施必要的监控和调节.

3.3回收范围与回收算法

回收范围: 方法区,堆.
回收频率:新生代>老年代>方法区
回收算法 1.垃圾阶段标记算法
垃圾标记阶段:主要是为了判断对象是否存活
1.在堆里存放着几乎所有的 Java 对象实例,在 GC 执行垃圾回收之前,首先需 要区分出内存中哪些是存活对象,哪些是已经死亡的对象。只有被标记为己经死亡的对象,GC 才会在执行垃圾回收时,释放掉其所占用的内存空间,因此这个 过程我们可以称为垃圾标记阶段。
2.那么在 JVM 中究竟是如何标记一个死亡对象呢?简单来说,当一个对象已经 不再被任何的存活对象继续引用时,就可以宣判为已经死亡。
3.判断对象存活一般有两种方式:引用计数算法(具有无法处理循环引用缺陷导致javaGC中没有使用该算法)和可达性分析算法。

3.4可达性分析算法

优点:1简单高效 ,2以有效地解决在引用计数算法中循环引用的问题,防止内存泄漏的发生.
算法原理:1.可达性分析算法是以根对象集合(GCRoots)为起始点,按照从上至下的方式 搜索被根对象集合所连接的目标对象是否可达。
2.使用可达性分析算法后,内存中的存活对象都会被根对象集合直接或间接连接 着,搜索所走过的路径称为引用链(Reference Chain)
3.如果目标对象没有任何引用链相连,则是不可达的,就意味着该对象己经死亡, 可以标记为垃圾对象。
4.在可达性分析算法中,只有能够被根对象集合直接或者间接连接的对象才是存 活对象。
其中 GCRoots可以表示的对象1.虚拟机栈中引用的对象2.本地方法栈内 JNI(通常说的本地方法)引用的对象3.方法区中类静态属性引用的对象4.方法区中常量引用的对象5.所有被同步锁 synchronized 持有的对象6.Java 虚拟机内部的引用.

4对象销毁前的回调函数finalize()

4.1Java 语言提供了对象终止(finalization)机制来允许开发人员提供对象被销毁 之前的自定义处理逻辑。
Java 语言提供了对象终止(finalization)机制来允许开发人员提供对象被销毁 之前的自定义处理逻辑。 当垃圾回收器发现没有引用指向一个对象,即:垃圾回收此对象之前,总会先调 用这个对象的 finalize()方法。 finalize() 方法允许在子类中被重写,用于在对象被回收时进行资源释放。通常 在这个方法中进行一些资源释放和清理的工作,比如关闭文件、套接字和数据库 连接等。
由于java中的回调函数finalize() 所以java中的对象并非脱离根节点即死亡,其具有三种可能出现的状态:
可触及的:从根节点开始,可以到达这个对象。
可复活的:对象的所有引用都被释放,但是对象有可能在 finalize()中复活。 不可触及的:对象的 finalize()被调用,并且没有复活,那么就会进入不可触及 状态。不可触及的对象不可能被复活,因为 finalize()只会被调用一次

5垃圾回收阶段算法

当成功区分出内存中存活对象和死亡对象后,GC 接下来的任务就是执行垃 圾回收,释放掉无用对象所占用的内存空间,以便有足够的可用内存空间为新对 象分配内存。目前在 JVM 中比较常见的三种垃圾收集算法是:
标记-清除算法(Mark-Sweep)
复制算法(Copying)
标记-压缩算法(Mark-Compact)

5.1标记-清除算法(Mark-Sweep)

优点:非常基础和常见的垃圾收集算法容易理解
缺点:标记清除算法的效率不算高
执行过程当堆中的有效内存空间(available memory)被耗尽的时候,就会停止整 个程序(也被称为 stop the world),然后进行两项工作,第一项则是标记,第二项则是清除
标记:Collector 从引用根节点开始遍历,标记所有被引用的对象。一般是 在对象的 Header 中记录为可达对象。(注意:标记的是被引用的对象,也就是 可达对象,并非标记的是即将被清除的垃圾对象)。
清除:Collector 对堆内存从头到尾进行线性的遍历,如果发现某个对象在 其 Header 中没有标记为可达对象,则将其回收。

5.2复制算法(Copying)

优点:没有标记和清除过程,实现简单,运行高效 复制过去以后保证空间的连续性,不会出现“碎片”问题
缺点:需要两倍的内存空间
它将可用内存按容量 划分为大小相等的两块,每次只使用其中的一块。在垃圾回收时将正在使用的内 存中的存活对象复制到未被使用的内存块中,之后清除正在使用的内存块中的所 有对象,交换两个内存的角色,最后完成垃圾回收。

5.3标记-压缩算法(Mark-Compact)

优点:消除了标记-清除算法当中,内存区域分散的缺点,我们需要给新对象分配内存 时,JVM 只需要持有一个内存的起始地址即可。 消除了复制算法当中,内存减半的高额代价。
缺点:从效率上来说,标记-整理算法要低于复制算法。 移动对象的同时,如果对象被其他对象引用,则还需要调整引用的地址 移动过程中,需要全程暂停用户应用程序。即:STW
第一阶段和标记清除算法一样,从根节点开始标记所有被引用对象
第二阶段将所有的存活对象压缩到内存的一端,按顺序排放。之后,清理边界外 所有的空间。

6.分代收集算法

分代收集算法,是基于这样一个事实:不同的对象的生命周期是不一样的。因此, 不同生命周期的对象可以采取不同的收集方式,以便提高回收效率。一般是把 Java 堆分为新生代和老年代,这样就可以根据各个年代的特点使用不同的回收 算法,以提高垃圾回收的效率。**目前几乎所有的 GC 都采用分代手机算法执行垃圾回收的.**基于分代的概念,GC 所使用的内存回收算法必须结合年轻代 和老年代各自的特点.

7.垃圾回收相关概念

内存溢出
内存溢出相对于内存泄漏来说,尽管更容易被理解,但是同样的,内存溢出也 是引发程序崩溃的罪魁祸首之一。 由于 GC 一直在发展,所有一般情况下,除非应用程序占用的内存增长速度非 常快,造成垃圾回收已经跟不上内存消耗的速度,否则不太容易出现 OOM 的情 况。大多数情况下,GC 会进行各种年龄段的垃圾回收,实在不行了就放大招,来 一次独占式的 Full GC 操作,这时候会回收大量的内存,供应用程序继续使用。 Javadoc 中对 OutofMemoryError 的解释是,没有空闲内存,并且垃圾收集 器也无法提供更多内存。
内存泄漏
内存泄漏也称作“存储渗漏”。严格来说,只有对象不会再被程序用到了,但 是 GC 又不能回收他们的情况,才叫内存泄漏。 但实际情况很多时候一些不太好的实践(或疏忽)会导致对象的生命周期变得 很长甚至导致 OOM,也可以叫做宽泛意义上的“内存泄漏”。 尽管内存泄漏并不会立刻引起程序崩溃,但是一旦发生内存泄漏,程序中的可 用内存就会被逐步蚕食,直至耗尽所有内存,最终出现 OutofMemory 异常, 导致程序崩溃.

8.垃圾回收器

8.1垃圾回收器概述

垃圾收集器没有在规范中进行过多的规定,可以由不同的厂商、不同版本的 JVM 来实现。 由于 JDK 的版本处于高速迭代过程中,因此 Java 发展至今已经衍生了众多 的 GC 版本。 从不同角度分析垃圾收集器,可以将 GC 分为不同的类型。

8.2垃圾回收器分类

按线程数分,可以分为串行垃圾回收器和并行垃圾回收器。
按照工作模式分,可以分为并发式垃圾回收器和独占式垃圾回收器。
按工作的内存区间分,又可分为年轻代垃圾回收器和老年代垃圾回收器。

9.垃圾收集器(CMS 回收器)

CMS(Concurrent Mark Sweep,并发标记清除)收集器是以获取最短回收停顿 时间为目标的收集器(追求低停顿),它在垃圾收集时使得用户线程和 GC 线 程并发执行,因此在垃圾收集过程中用户也不会感到明显的卡顿。
初始标记:Stop The World,仅使用一条初始标记线程对所有与 GC Roots 直接关联的对象进行标记。
并发标记:使用多条标记线程,与用户线程并发执行。此过程进行可达性 分析,标记出所有废弃对象。速度很慢。
重新标记:Stop The World,使用多条标记线程并发执行,将刚才并发 标记过程中新出现的废弃对象标记出来。
并发清除:只使用一条 GC 线程,与用户线程并发执行,清除刚才标记 的对象。这个过程非常耗时。 并发标记与并发清除过程耗时最长,且可以与用户线程一起工作,因此,总体上 说,CMS 收集器的内存回收过程是与用户线程一起并发执行的。
CMS 的优点: 并发收集 低延迟
CMS 的弊端: 1. 会产生内存碎片,导致并发清除后,用户线程可用的空间不足。在无法分配 大对象的青况下,不得不提前触发 Ful1 GC.
2.CMS 收集器对 CPU 资源非常敏感。在并发阶段,它虽然不会导致用户停顿, 但是会因为占用了一部分线程而导致应用程序变慢,总吞吐量会降低。 3.CMS 收集器无法处理浮动垃圾。可能出现"Concurrent Mode Failure"失败而 导致另一次 Full GC 的产生。在并发标记阶段由于程序的工作线程和垃圾收集线 程是同时运行或者交叉运行的,那么在并发标记阶段如果产生新的垃圾对象, CMS 将无法对这些垃圾对象进行标记,最终会导致这些新产生的垃圾对象没有 被及时回收,从而只能在下一次执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值