JAVA(GC)线程的生命

本文详细介绍了Java的垃圾回收机制,包括垃圾的定义、GC(垃圾收集器)的作用、自动内存管理及其问题、可达性分析算法、垃圾回收阶段的各种算法如标记-清除、复制和标记-压缩等。还提到了分代收集算法以及CMS(并发标记清除)收集器,强调了CMS的低延迟特点和潜在问题。此外,讨论了内存溢出和内存泄漏的区别和影响,以及垃圾回收器的分类。

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 将无法对这些垃圾对象进行标记,最终会导致这些新产生的垃圾对象没有 被及时回收,从而只能在下一次执行。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值