1 判断对象是否可回收有几种方式?

  1. 引用计数算法

优点:实现简单,判定高效;

缺点:很难解决对象之间相互循环引用的问题;

  1. 可达性分析算法

通过一系列"GC Roots"对象作为起始点,开始向下搜索,当一个对象到GC Roots没有任何引用链相连时(从GC Roots到这个对象不可达),则证明该对象是不可用的;

优点:更加精确和严谨,可以分析出循环数据结构相互引用的情况

缺点:实现比较复杂;需要分析大量数据,消耗大量时间;分析过程需要GC停顿(引用关系不能发生变化),即停顿所有Java执行线程(称为"Stop The World",是垃圾回收重点关注的问题)

2 "GC Roots"对象都包含哪些

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

3 Java四种引用类型分别是什么?及存活时间

  1. 强引用:程序代码普遍存在的,类似"Object obj=new Object()";只要强引用还存在,GC永远不会回收被引用的对象;
  2. 软引用:描述还有用但并非必需的对象;直到内存空间不够时(抛出OutOfMemoryError之前),才会被垃圾回收;最常用于实现对内存敏感的缓存;SoftReference类实现;
  3. 弱引用:用来描述非必需对象;只能生存到下一次垃圾回收之前,无论内存是否足够;WeakReference类实现;
  4. 虚引用:完全不会对其生存时间构成影响;唯一目的就是能在这个对象被回收时收到一个系统通知;PhantomRenference类实现;

4 Java四种引用使用场景

  1. 强引用-FinalReference

地球人都知道,但是我讲不出来;

  1. 软引用-SoftReference

创建缓存的时候,创建的对象放进缓存中,当内存不足时,JVM就会回收早先创建的对象。PS:图片编辑器,视频编辑器之类的软件可以使用这种思路。

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

  1. 弱引用-WeakReference

Java源码中的java.util.WeakHashMap中的key就是使用弱引用,一旦不需要某个引用,JVM会自动处理它,这样就不需要做其它操作。

弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

  1. 虚引用-PhantomReference

主要用来跟踪对象被垃圾回收器回收的活动。虚引用的回收机制跟弱引用差不多,但是它被回收之前,会被放入ReferenceQueue中。注意哦,其它引用是被JVM回收后才被传入ReferenceQueue中的。由于这个机制,所以虚引用大多被用于引用销毁前的处理工作。

程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

对象销毁前的一些操作,比如说资源释放等。Object.finalize()虽然也可以做这类动作,但是这个方式即不安全又低效。

5 JVM如何进行对象标记

  1. 第一次标记:在可达性分析后发现到GC Roots没有任何引用链相连时,被第一次标记;并且进行一次筛选:此对象是否必要执行finalize()方法;没有必要执行的情况,则标记对象已死;有必要执行的情况,则对象被放入F-Queue队列中;
  2. 第二次标记:GC将对F-Queue队列中的对象进行第二次小规模标记;finalize()方法是对象逃脱死亡的最后一次机会;一个对象的finalize()方法只会被系统自动调用一次,经过finalize()方法逃脱死亡的对象,第二次不会再调用;

6 为何不建议使用finalize()方法

因为其执行的时间不确定,甚至是否被执行也不确定(Java程序的不正常退出),而且运行代价高昂,无法保证各个对象的调用顺序(甚至有不同线程中调用);如果需要"释放资源",可以定义显式的终止方法,并在"try-catch-finally"的finally{}块中保证及时调用;

如果有关键资源,必须显式的终止方法;一般情况下,应尽量避免使用它,甚至可以忘掉它;

7 什么是安全点,为什么需要

运行中,非常多的指令都会导致引用关系变化;如果为这些指令都生成对应的OopMap,需要的空间成本太高;

只在特定的位置记录OopMap引用关系,这些位置称为安全点(Safepoint);

8 如何选定安全点

不能太少,否则GC等待时间太长;也不能太多,否则GC过于频繁,增大运行时负荷;

所以,基本上是以程序"是否具有让程序长时间执行的特征"为标准选定,如:方法调用、循环跳转、循环的末尾、异常跳转等;

只有具有这些功能的指令才会产生Safepoint;

9 如何使Java线程在安全点上停顿

  1. 抢先式中断(Preemptive Suspension):在GC发生时,首先中断所有线程;如果发现不在Safepoint上的线程,就恢复让其运行到Safepoint上;
  2. 主动式中断(Voluntary Suspension):在GC发生时,不直接操作线程中断,而是仅简单设置一个标志;让各线程执行时主动去轮询这个标志,发现中断标志为真时就自己中断挂起;
  3. 而轮询标志的地方和Safepoint是重合的;

10 什么是安全区域,为什么需要安全区域

线程不执行时没有CPU时间(Sleep或Blocked状态),无法运行到Safepoint上再中断挂起;

安全区域:指一段代码片段中,引用关系不会发生变化;在这个区域中的任意地方开始GC都是安全的;

11 如何使用安全区域解决问题

  1. 线程执行进入Safe Region,首先标识自己已经进入Safe Region;
  2. 线程被唤醒离开Safe Region时,其需要检查系统是否已经完成根节点枚举(或整个GC);
  3. 如果已经完成,就继续执行;否则必须等待,直到收到可以安全离开Safe Region的信号通知,这样就不会影响标记结果;

12 GC算法:标记-清楚优缺点

优点:基于最基础的可达性分析算法,它是最基础的收集算法;而后续的收集算法都是基于这种思路并对其不足进行改进得到的;

缺点:效率问题,标记和清除两个过程的效率都不高;空间问题,标记清除后会产生大量不连续的内存碎片;这会导致分配大内存对象时,无法找到足够的连续内存;从而需要提前触发另一次垃圾收集动作;

13 GC算法:复制算法优缺点

优点:使得每次都是只对整个半区进行内存回收;内存分配时也不用考虑内存碎片等问题;实现简单,运行高效;

缺点:空间浪费;效率随对象存活率升高而变低;

14 GC算法:HotSpot虚拟机复制算法

  1. 将新生代内存分为一块较大的Eden空间和两块较小的Survivor空间;
  2. 每次使用Eden和其中一块Survivor;
  3. 当回收时,将Eden和使用中的Survivor中还存活的对象一次性复制到另外一块Survivor;
  4. 而后清理掉Eden和使用过的Survivor空间;
  5. 后面就使用Eden和复制到的那一块Survivor空间,重复步骤3;

默认Eden:Survivor=8:1,即每次可以使用90%的空间,只有一块Survivor的空间被浪费;

15 什么是分配担保

如果另一块Survivor空间没有足够空间存放上一次新生代收集下来的存活对象时,这些对象将直接通过分配担保机制(Handle Promotion)进入老年代;

16 GC算法:标记-整理优缺点

优点:不会产生内存碎片;

缺点:增加了对存活对象需要整理的过程,效率更低;

17 分代收集算法

"分代收集"(Generational Collection)算法结合不同的收集算法处理不同区域。

新生代:每次垃圾收集都有大批对象死去,只有少量存活;所以可采用复制算法;

老年代:对象存活率高,没有额外的空间可以分配担保;使用"标记-清理"或"标记-整理"算法;

优点:根据各个年代的特点采用最适当的收集算法;

缺点:仍然不能控制每次垃圾收集的时间;

18 G1垃圾收集算法

19 JVM有哪些收集器?分别用于哪些代?

JDK7/8后,HotSpot虚拟机所有收集器及组合(连线),如下图:

新生代收集器:Serial、ParNew、Parallel Scavenge; 老年代收集器:Serial Old、Parallel Old、CMS; 整堆收集器:G1;

20 Serial收集器

新生代、复制算法、单线程收集;

缺点:进行垃圾收集时,必须暂停所有工作线程,直到完成;即会"Stop The World";

Serial/Serial Old组合收集器运行示意图如下

21 ParNew收集器

新生代、复制算法、多线程收集;

缺点:进行垃圾收集时,必须暂停所有工作线程,直到完成;即会"Stop The World";

ParNew/Serial Old组合收集器运行示意图如下

22 Parallel Scavenge收集器

新生代、复制算法、多线程收集;

CMS等收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间;而Parallel Scavenge收集器的目标则是达一个可控制的吞吐量(Throughput);

23 Serial Old收集器

老年代、"标记-整理"算法(还有压缩,Mark-Sweep-Compact)、单线程收集;

24 Parallel Old收集器

老年代、"标记-整理"算法(还有压缩,Mark-Sweep-Compact)、多线程收集;

25 CMS收集器

老年代、"标记-清除"算法(不进行压缩操作,产生内存碎片)、并发收集、低停顿

CMS收集器运行示意图如下

整个过程中耗时最长的并发标记和并发清除都可以与用户线程一起工作;所以总体上说,CMS收集器的内存回收过程与用户线程一起并发执行;

CMS收集器3个明显的缺点

  1. 对CPU资源非常敏感;
  2. 无法处理浮动垃圾,可能出现"Concurrent Mode Failure"失败;
  3. 产生大量内存碎片;

26 G1收集器

27 JVM如何进行对象内存分配

在堆上分配(JIT编译优化后可能在栈上分配),主要在新生代的Eden区中分配;

如果启用了本地线程分配缓冲,将线程优先在TLAB上分配;

少数情况下,可能直接分配在老年代中;

分配的细节取决于当前使用哪种垃圾收集器组合,以及JVM中内存相关参数设置;

28 哪些情况下对象内存分配会直接进入老年代

  1. 当Eden区没有足够空间进行分配时,JVM将发起一次Minor GC(新生代GC);Minor GC时,如果发现存活的对象无法全部放入Survivor空间,只好通过分配担保机制提前转移到老年代。
  2. 需要大量连续内存空间的Java大对象会直接进入老年代,容易提前触发老年代GC;
  3. 经过多次Minor GC,如果年龄达到一定程度,就晋升到老年代;
  4. 动态对象年龄判定:如果在Survivor空间中相同年龄的所有对象大小总和大于Survivor空间的一半,大于或等于该年龄的对象就可以直接进入老年代;

29 方法区中可回收哪些对象

  1. 废弃常量:与回收Java堆中对象非常类似;
  2. 无用的类:(1)该类所有实例都已经被回收(即Java椎中不存在该类的任何实例);(2)加载该类的ClassLoader已经被回收,也即通过引导程序加载器加载的类不能被回收;(3)该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法;

30 JDK HotSpot虚拟机方法区调整

  1. 在JDK7中,使用永久代(Permanent Generation)实现方法区,这样就可以不用专门实现方法区的内存管理,但这容易引起内存溢出问题;
  2. 在JDK8中,永久代已被删除,类元数据(Class Metadata)存储空间直接在本地内存中分配;

技术问答集锦(17)JVM垃圾回收相关推荐

  1. JVM 垃圾回收算法机制及其实现原理

    前言 对于 JVM 来说,我们都不陌生,其是 Java Virtual Machine(Java 虚拟机)的缩写,它也是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的.JV ...

  2. 11 JVM 垃圾回收(上)

    11 JVM 垃圾回收(上) 引用计数法和可达性分析 垃圾回收,就是将已经分配出去的,但却不在使用的内存回收回来,以便再次分配.在 Java 虚拟机语境下,垃圾指的是死亡的对象所占据的堆空间.下面就总 ...

  3. JVM架构、JVM垃圾回收机制、垃圾回收算法、垃圾回收器、JMM(内存模型)

    0 JVM和Java的关系 JDK = JRE + Java开发工具(java,javac,javadoc,javap-) JRE = JVM + Java核心类库 即: JDK = JVM + Ja ...

  4. 深入理解JVM虚拟机2:JVM垃圾回收基本原理和算法

    JVM GC基本原理与GC算法 Java的内存分配与回收全部由JVM垃圾回收进程自动完成.与C语言不同,Java开发者不需要自己编写代码实现垃圾回收.这是Java深受大家欢迎的众多特性之一,能够帮助程 ...

  5. JVM垃圾回收算法与原理详解

    垃圾回收 参考文档 GC参考手册-Java版 理解Java的强引用.软引用.弱引用和虚引用 JVM系列(五) - JVM垃圾回收算法 如何判断对象可以回收 引用计数法 参考文章 Java JVM的引用 ...

  6. jvm垃圾回收机制_JVM的垃圾回收机制总结

    一.了解技术背景 按照套路是要先装装X,谈谈JVM垃圾回收的前世今生的.说起垃圾回收(GC),大部分人把这项技术当做Java语言的伴生产物.事实上,GC的历史比Java久远,早在1960年Lisp这门 ...

  7. jvm对象从新生代到老年代_JVM内存管理、JVM垃圾回收机制、新生代、老年代以及永久代...

    内存模型 JVM运行时数据区由程序计数器.堆.虚拟机栈.本地方法栈.方法区部分组成,结构图如下所示. JVM内存结构由程序计数器.堆.栈.本地方法栈.方法区等部分组成,结构图如下所示: 1)程序计数器 ...

  8. JVM内存区域(Java内存区域)、JVM垃圾回收机制(GC)初探

    一.JVM内存区域(Java内存区域) 首先区分一下JVM内存区域(Java内存区域)和Java内存模型(JMM)的概念.Java线程之间的通信采用的是共享内存模型,这里提到的共享内存模型指的就是Ja ...

  9. JVM垃圾回收——G1垃圾收集器

    目录 一.什么是G1垃圾收集器 二.G1垃圾收集器的内存划分 三.G1垃圾收集器的收集过程 四.G1收集器的优缺点 五.G1收集器的JVM参数配置 一.什么是G1垃圾收集器 Garbage First ...

  10. 细谈JVM垃圾回收与部分底层实现

    JVM系列文章目录 初识JVM 深入理解JVM内存区域 玩转JVM对象和引用 JVM分代回收机制和垃圾回收算法 细谈JVM垃圾回收与部分底层实现 Class文件结构及深入字节码指令 玩转类加载和类加载 ...

最新文章

  1. STL的remove函数和list的remove成员函数
  2. 【C 语言】动态库封装与设计 ( Windows 动态库简介 | Visual Studio 调用动态库 )
  3. 双代号网络图节点编号原则_『干货』二级建造师考试高频考点 双代号网络图的详细解析...
  4. c#如何识别一张图片的格式
  5. java 集合操作工具包_java之操作集合的工具类--Collections
  6. 腾讯开奖,应届生年薪40万,白菜价,薪资倒挂!
  7. Linux开机启动过程(12):start_kernel()->还是setup_arch
  8. 幻速s3_藏在“L”背后的故事 体验北汽幻速-S3L
  9. 【lnmp一键安装包】LNMP一键安装和配置(解决LNMP502和500问题)
  10. 三目表达式的个人总结
  11. 分享干货——数控加工中常用的三种补偿方法
  12. 关于Ubuntu 无法正常关机的问题
  13. 7-1 计算职工工资c语言,C语言职工工资管理系统
  14. voip 音频采集时间_树莓派3 音频配置及其应用场景(录音、VoIP 电话等)(锁定重发)...
  15. 组合数学$1排列组合
  16. python实现打电话功能_使用python代码调用三汇语音卡硬件拨打电话
  17. python ppt转图片_ppt一键转图片和pdf
  18. SAP MI01、MI04、MI07、MI10 批量盘点凭证创建+盘点数量+差异过账
  19. 双目立体视觉简单介绍
  20. JS一元运算符(前++,后++)详解

热门文章

  1. Java数组相关知识
  2. 系统协调服务器,协调网络系统 Collaboration network system
  3. android 组件化_你曾遇到的某大厂奇葩问题:Android组件化开发,组件间的Activity页面跳转...
  4. 比较好的电脑系统_效果好的筛分移动破碎站有优惠吗?
  5. java策略_java策略模式
  6. 怎么查看WordPress主题HTML,几个WordPress 主题在线检测工具
  7. java excel 晒新年操作_JAVA使用POI操作excel
  8. Js Date对象 简单操作
  9. 事务四大特性及隔离级别
  10. 安卓学习笔记33:实现逐帧动画