什么是垃圾回收:
垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的对象,按照特定的垃圾回收算法来实现资源自动回收。
java中的垃圾回收机制:
Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用空闲的内存。
注:内存泄露是指该内存空间使用完毕之后未回收,在不涉及复杂数据结构的一般情况下,Java 的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度,我们有时也将其称为“对象游离”。
垃圾回收的好处和特点:
好处:
1. 提高编程效率;
2. 垃圾回收机制保护程序的完整性。
特点:
1. 只能回收无用对象的内存空间,对其他物理资源无能为力;
2. 为了更快回收不再使用的对象,可以将对象的引用变量设置为null
3. 垃圾回收不可预知性(不同的垃圾回收机制和不同的垃圾回收算法)
jvm垃圾回收算法:
Java语言规范没有明确地说明JVM使用哪种垃圾回收算法,但是任何一种垃圾回收算法一般要做2件基本的事情:(1)发现无用信息对象;(2)回收被无用对象占用的内存空间,使该空间可被程序再次使用。
引用计数:
比较古老的回收算法,原理是此对象有一个引用,既增加一个计数删除一 个则减少一个计数,垃圾回收时只用收集计数为0的对象,无法处理循环 引用的问题。(已经不用了)
根可达算法:
通过根可达算法的基础上:
复制:
把内存空间划分为两个相等的区域,每次只是用其中一个区域,垃圾回收时遍历当前使用区域,吧正在使用中的对象复制到另一个区域中,次算法每次只处理正在使用的对象,因此复制成本较小,同时复制过去以后还能进行相应的内存整理,不会出现碎片问题。但是占用空间使用原来的两倍内存空间
标记-清除:
此算法分为两步:先从引用的根节点开始标记所有被引用的对象,在遍历整个堆,将未标记的对象进行清除,次算法需要暂停整个应用。同时会产生内存碎片。
标记-整理:
此算法结合了标记-清除和复制两个算法的优点,也分配了两个阶段:先从根节点开始标记所有引用的对象,在遍历整个堆,清除未标记的对象,并且将存活的对象放在一起,按顺序进行排放,避免了碎片问题和复制算法的空间问题
分代收集算法:
一般分为新生代与老年代他们的内存比例分配为8:2
新生代一般使用的是复制算法;
老年代使用的是整理算法
分代策略:
新生代(young):eden from to
新生成的对象先放在新生代中,他的回收率在70-95%左右,
他们的空间默认比例为8:1:1 因为Hotspot采用复制算法进行新生代 回收的,是为了充分利用内存空间,减少浪费,当eden空间满后进行回 收,回收后的复制到from 区中,当他打到一定的阀值后进入to区。from 与to区是可转换的,每次gc完后 to 区都是空的。如果没有足够的空间时会 依赖老年代进行分担数据。
老年代(old):
在新生代中经历了多次gc后还存活的对象会进入到老年区,老年代中的对 象生命周期长,在老年代中进行gc频率低,且相对而言时间长速度慢。
永久代(Permanent):
永久代存储类信息,常量,静态变量,及时编译器编译后的代码等数据。 对这一区域二样,java虚拟机规范支出可以不进行垃圾回收,一般也不会进 行垃圾回收
注意:在java1.8之后可能就没有了永久代了(还需验证)
增量收集算法:
增量算法前提:
现有算法,在垃圾回收过程中,应用软件将处于一种Stop the World 的状 态。在Stop the World 状态下,应用程序所有的线程都会挂起,暂停一切正常 的工作,等待垃圾回收的完成。如果垃圾回收时间过长,应用程序会被挂起很 久,将严重影响用户体验或者系统的稳定性。为了解决这个问题,即对实时垃 圾收集算法的研究直接导致了增量收集(Incremental Collecting)算法的诞 生。
基本思想:
如果一次性将所有的垃圾进行处理,需要造成系统长时间的停顿,那么就可以让垃圾收集线程和应用程序线程交替执行。每次,垃圾收集线程只收集一小片区域的内存空间,接着切换到应用程序线程。依次反复,直到垃圾收集完成。
总的来说,增量收集算法的基础仍是传统的标记-清除和复制算法。增量收集算法通过对线程间冲突的妥善处理,允许垃圾收集线程以分阶段的方式完成标记、清理或复制工作。
缺点:
线程切换和上下文转换的消耗,会使得垃圾回收的总体成本上升,造成系统吞吐量的下降
补充:Stop the World 的状态(STW)
等待所有用户线程进入安全点后并阻塞,做一些全局性操作的行为。
当程序运行到这些“安全点”的时候就会暂停所有当前运行的线程(Stop The World 所以叫STW),暂停后再找到“GC Roots”进行关系的组建,进而执行标记和清除。
在执行垃圾收集算法时,Java应用程序的其他所有线程都被挂起(除了垃圾收集帮助器之外)。Java中一种全局暂停现象,全局停顿,所有Java代码停止,native代码可以执行,但不能与JVM交互;这些现象多半是由于gc引起。
了解stw 址:
https://blog.csdn.net/weixin_44704538/article/details/108222022
具体后续会慢慢更新,不足之处,希望大佬多多指点。
文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览91437 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!