JVM——垃圾收集(GC)

引言

1、什么是GC?
garbage collector

2、GC要做的事?

  • 1、Where/Which?
  • 2、When?
  • 3、How?

3、为什么我们要去了解GC和内存分配?

  • 1、面试需要
  • 2、GC对应用的性能是有影响的
  • 3、写代码有好处

4、谁需要GC?
GC(垃圾收集)主要是针对堆和方法区进行。程序计数器、虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后就会消失,因此不需要对这三个区域进行垃圾回收。

判断对象的存活

一、引用计数算法

为对象添加一个引用计数器,当对象增加一个引用时计数器加 1,引用失效时计数器减 1。引用计数为 0 的对象可被回收。

缺点:在两个对象出现循环引用的情况下,此时引用计数器永远不为 0,导致无法对它们进行回收。正是因为循环引用的存在,因此 Java 虚拟机不使用引用计数算法。

二、可达性分析算法

以 GC Roots 为起始点进行搜索,搜索所走过的路径称为引用链,可达的对象都是存活的,不可达的对象可被回收。当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是可以被回收的。
可达性分析
Java 虚拟机使用该算法来判断对象是否可被回收,GC Roots 一般包含以下内容:

  • 1、方法区: 类静态属性引用的对象。
  • 2、方法区: 常量引用的对象。
  • 3、虚拟机栈(本地变量表)中引用的对象.。
  • 4、本地方法栈JNI(Native方法)中引用的对象。

引用类型

Java 提供了四种强度不同的引用类型。

一、强引用

被强引用关联的对象不会被回收。

使用 new 一个新对象的方式来创建强引用。

Object obj = new Object();

二、软引用 SoftReference

被软引用关联的对象只有在内存不够的情况下才会被回收。也就是系统将要发生OOM之前,这些对象就会被回收。

使用 SoftReference 类来创建软引用。

Object obj = new Object();
SoftReference<Object> sf = new SoftReference<Object>(obj);
obj = null;  
// 使对象只被软引用关联
三、弱引用 WeakReference

被弱引用关联的对象一定会被回收,也就是说用弱引用关联的对象,只能生存到下一次垃圾回收之前,GC发生时,不管内存够不够,都会被回收。

使用 WeakReference 类来创建弱引用。

Object obj = new Object();
WeakReference<Object> wf = new WeakReference<Object>(obj);
obj = null;
四、虚引用 PhantomReference

又称为幽灵引用或者幻影引用,一个对象是否有虚引用的存在,不会对其生存时间造成影响,也无法通过虚引用得到一个对象。

为一个对象设置虚引用的唯一目的是能在这个对象被回收时收到一个系统通知

使用 PhantomReference 来创建虚引用。

Object obj = new Object();
PhantomReference<Object> pf = new PhantomReference<Object>(obj);
obj = null;

垃圾收集算法

一、标记-清除算法(Mark-Sweep)

标记清除算法
标记要回收的对象,然后清除。

缺点:
1、标记和清除过程效率都不高;
2、会产生大量不连续的内存碎片,导致无法给大对象分配内存。

二、标记-整理算法(Mark-Compact)

标记整理算法
标记无用对象,让所有存活的对象都向一端移动,然后直接清除掉端边界以外的内存。

三、复制算法(Copying)

复制算法
按照容量划分二个大小相等的内存区域,每次只使用其中一块,当一块用完的时候将活着的对象复制到另一块上,然后再把已使用的内存空间一次清理掉。

缺点:内存使用率不高,只有原来的一半。

现在的商业虚拟机都采用这种收集算法回收新生代,但是并不是划分为大小相等的两块,而是一块较大的 Eden 空间和两块较小的 Survivor 空间,每次使用 Eden 和其中一块 Survivor。在回收时,将 Eden 和 Survivor 中还存活着的对象全部复制到另一块 Survivor 上,最后清理 Eden 和使用过的那一块 Survivor。

HotSpot 虚拟机的 Eden 和 Survivor 大小比例默认为 8:1,保证了内存的利用率达到 90%。如果每次回收有多于 10% 的对象存活,那么一块 Survivor 就不够用了,此时需要依赖于老年代进行空间分配担保,也就是借用老年代的空间存储放不下的对象。

四、分代收集算法

根据对象存活周期的不同将内存划分为几块,不同块采用适当的收集算法。一般是新生代和老年代,新生代基本采用复制算法,老年代采用标记-清除或者标记-整理算法。

垃圾收集器

下面是 HotSpot 虚拟机中的 7 个垃圾收集器,连线表示垃圾收集器可以配合使用。
垃圾收集器
单线程与多线程
单线程指的是垃圾收集器只使用一个线程,而多线程使用多个线程。

串行与并行
串行指的是垃圾收集器与用户程序交替执行,这意味着在执行垃圾收集的时候需要停顿用户程序;并行指的是垃圾收集器和用户程序同时执行。除了 CMS 和 G1 之外,其它垃圾收集器都是以串行的方式执行。

一、Serial 收集器

Serial
Serial [ˈsɪəriəl] 翻译为串行,也就是说它以串行的方式执行。

它是最早的单线程串行垃圾回收器,只会使用一个线程进行垃圾收集工作。

它的优点是简单高效,在单个 CPU 环境下,由于没有线程交互的开销,因此拥有最高的单线程收集效率。

它是 Client 场景下的默认新生代收集器,因为在该场景下内存一般来说不会很大。它收集一两百兆垃圾的停顿时间可以控制在一百多毫秒以内,只要不是太频繁,这点停顿时间是可以接受的。

二、ParNew 收集器

ParNew
它是 Serial 收集器的多线程版本。

它是 Server 场景下默认的新生代收集器,除了性能原因外,主要是因为除了 Serial 收集器,只有它能与 CMS 收集器配合使用。

三、Parallel Scavenge 收集器

与 ParNew 一样是多线程收集器。

其它收集器目标是尽可能缩短垃圾收集时用户线程的停顿时间,而它的目标是达到一个可控制的吞吐量,因此它被称为“吞吐量优先”收集器。这里的吞吐量指 CPU 用于运行用户程序的时间占总时间的比值。

停顿时间越短就越适合需要与用户交互的程序,良好的响应速度能提升用户体验。而高吞吐量则可以高效率地利用 CPU 时间,尽快完成程序的运算任务,适合在后台运算而不需要太多交互的任务。

缩短停顿时间是以牺牲吞吐量和新生代空间来换取的:新生代空间变小,垃圾回收变得频繁,导致吞吐量下降。

可以通过一个开关参数打开 GC 自适应的调节策略(GC Ergonomics),就不需要手工指定新生代的大小(-Xmn)、Eden 和 Survivor 区的比例、晋升老年代对象年龄等细节参数了。虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是几个 JVM 垃圾回收相关的面试题及其答案: 1. 什么是垃圾回收? 垃圾回收是指在程序运行过程中,自动回收不再使用的内存空间,以提高内存利用率和程序的性能。 2. JVM垃圾回收机制是什么? JVM垃圾回收机制采用分代收集算法,将内存分为新生代和老年代,分别采用不同的垃圾回收算法来回收内存。 3. 新生代垃圾回收器有哪些? 新生代垃圾回收器主要有 Serial、ParNew、Parallel Scavenge 等。 4. 老年代垃圾回收器有哪些? 老年代垃圾回收器主要有 Serial Old、Parallel Old、CMS、G1 等。 5. 什么是对象的引用计数算法? 引用计数算法是一种简单的垃圾回收算法,它通过记录每个对象被引用的次数,当引用次数为 0 时,即可将该对象回收。 6. 引用计数算法的缺点是什么? 引用计数算法的缺点是无法处理循环引用的情况,如果两个对象之间相互引用,它们的引用计数会一直不为 0,导致无法回收。 7. 什么是标记-清除算法? 标记-清除算法是一种常见的垃圾回收算法,它将垃圾回收分为两个阶段:标记阶段和清除阶段。在标记阶段,标记所有活跃对象,将其打上标记;在清除阶段,清除所有未标记的对象。 8. 标记-清除算法的缺点是什么? 标记-清除算法的缺点是会产生大量的内存碎片,会导致内存利用率降低。 以上是一些常见的 JVM 垃圾回收面试题及其答案,希望能对你有所帮助。在面试过程中,需要根据具体的问题进行回答,同时也需要对垃圾回收机制和算法有清晰的认识,才能更好地回答相关的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值