对象是否存活

Java的GC基于可达性分析算法(Python用引用计数法),通过可达性分析来判定对象是否存活。这个算法的基本思想是通过一系列"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时(图论称之为不可达),则证明此对象是不可用的。

无论引用计数法,还是可达性分析都离不开“引用”的概念。Java将引用分为四种(强引用、软引用,弱引用,虚引用),这四种引用强度依次逐渐减弱。

strong reference强引用,垃圾收集器永远不会回收存在强引用的对象。(如Object obj = new object()就是一个强引用)

soft reference软引用,描述一些还有用但是并非必须的对象。系统将要发生内存溢出异常之前,将会把这些软引用对象列入回收范围中进行二次回收。如果这次回收之后还是不够内存,才会抛出内存溢出异常。

weak reference弱引用,也是用来描述非必须对象的,但是它的强度更弱。被弱引用的对象只能活到下一次GC发生之前。当GC发生,无论当前内存是否充足都会回收弱引用对象。

phantom reference虚引用(幽灵引用),是最弱的一种引用关系。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。

在可达性算法中不可达的对象,不会直接死亡,如果它还没有执行finalize方法,虚拟机将在一个优先级很低的线程中触发它的finalize方法(不保证完成),如果此时对象又将自己关联到引用链上,那么GC将把它移出“即将回收”的集合。

由于finalize方法只会被执行一次,所以这个“自救”过程也只会经历一次。

垃圾回收方法

1、标记清除法

首先标记所有需要回收的对象,然后统一回收所有要回收的对象。方法简单,但是效率不高,并且产生了很多内存碎片。

2、复制算法

将内存分为大小相等的两块,每次只使用一块。当一块的内存用完了,就将还存活的对象复制到另一块内存上,然后把使用过的那一半内存空间一次性清理掉。这样再分配内存时只需要移动堆顶指针,实现简单,运行高效。但是代价是实际可用内存缩小了一半,实在太高。

因为新生代大部分对象都是”朝生夕死“,所以虚拟机将内存分为1个Eden和2个Survivor空间,大小比例默认为8:1:1。当回收时,将Eden和Survivor中还存活着的对象复制到另一个Survivor空间上,然后清理掉Eden和刚才用过的Survivor空间。这样子就只需要牺牲10%的新生代内存。

分配担保:因为存在1个Survivor空间存放不了Eden和另一个Survivor空间的对象的情况,此时那些存活的对象由于无法放入该Survivor空间,将直接进入老年代。)

3、标记-整理算法

老年代对象存活率高,复制算法在这时候效率很低,而且老年代没有额外空间做分配担保,所以不适用。根据这种特点,有人提出了标记-整理算法。

首先标记所有要回收的对象,然后所有存活的对象都向一端移动,然后直接清理边界以外的内存。

4、分代收集算法

前面三个垃圾回收算法都算是铺垫,现在商业虚拟机的垃圾收集都采用”分代收集“。将Java堆分成新生代和老年代,新生代中每次GC有大量对象死去,只有少量存活,所以采用复制算法;老年代中对象存活率高,没有额外空间进行分配担保,就采用标记-清除或者标记-整理算法。

垃圾收集器

新生代:serial收集器

单线程,必须暂停其他所有工作线程(Stop The World),直到它收集结束。STW难以接受,但是简单高效。

新生代:parNew收集器

serial的多线程版本。server模式下首选,因为它可以和cms配合使用。

新生代:parallel scavenge收集器

专注于达到可控制吞吐量的收集器,主要适合后台运算而不用太多交互的任务。

老年代:serial old收集器

serial的老年代版本,单线程。使用标记-整理算法。

老年代:parallel old收集器

parallel scavenge的老年代版本。使用标记-整理算法。

老年代:cms收集器

经历四个阶段:

初始标记:需要STW,仅仅标记一下GC Roots能直接关联的对象,所以很快。

并发标记:进行GC Roots Tracing

重新标记:需要STW,修正并发标记期间因程序运行导致标记产生变动的那一部分对象的标记记录,时间比初始标记长,但是远比并发标记短

并发清除:清除对象

由于耗时最长的并发标记和并发清除过程,收集器线程都可以和用户线程一起工作,所以总体来说cms收集器的内存回收过程是和用户线程一起并发执行的,停顿很短。

缺点:cpu资源敏感,特别是cpu核数较少时;无法处理浮动垃圾;cms基于标记-清除算法,容易产生大量内存碎片。

G1收集器

最新的收集器,性能优秀,但是太复杂不再赘述。

内存分配和回收策略

对象优先在Eden分配,如果启动了TLAB,将按照线程优先在TLAB上分配。

当Eden不够空间时,虚拟机发起一次Minor GC(新生代GC)

大对象直接进入老年代

长期存活的对象将进入老年代(存活一次GC age+1,默认age 15时进入老年代)

Survivor空间中相同年龄所有年龄大小 的总和大于Survivor空间的一半 时,年龄大于等于该年龄的对象可以直接进入老年代

Minor GC时,虚拟机会检查老年代的剩余空间是否大于新生代对象总大小or历次晋升的平均大小,如果是那么就会进行Minor GC,否则认为老年代无法提供分配担保,进行Full GC。

欢迎工作一到八年的Java工程师朋友们加入Java高级交流群:828697593

本群提供免费的学习指导 架构资料 以及免费的解答

不懂得问题都可以在本群提出来 之后还会有直播平台和讲师直接交流噢

哦对了,喜欢就别忘了关注一下哦~

转载于:https://juejin.im/post/5c0cd1bc518825501076b518

深入理解JVM——虚拟机GC相关推荐

  1. java虚拟机内存监控_深入理解JVM虚拟机9:JVM监控工具与诊断实践

    本文转自: https://juejin.im/post/59e6c1f26fb9a0451c397a8c 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到 ...

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

    本文转自互联网,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 喜欢的话麻烦点下Star哈 文章将同步到我的个人博客: www.how ...

  3. 深入理解JVM虚拟机之垃圾回收

    深入理解JVM虚拟机之垃圾回收 什么叫做垃圾? 没有引用指向得对象都称为垃圾,好比如我们放风筝,哪些断了线得风筝都称之为垃圾. JVM怎么查找这些垃圾 一般又两种算法,1.可达性分析.2.引用计数 引 ...

  4. java visualvm远程监控_深入理解JVM虚拟机12:JVM性能管理神器VisualVM介绍与实战

    本文转自互联网,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutori ...

  5. 接口多个实现类加载哪个_深入理解JVM虚拟机7:JNDI,OSGI,Tomcat类加载器实现

    本文转自互联网,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutori ...

  6. 深入理解JVM虚拟机_4 JVM内部结构分析-栈

    深入理解JVM虚拟机_4 JVM内部结构分析-栈 作者:田超凡 原创博文,仿冒必究,部分素材转载自每特教育蚂蚁课堂 栈 1. Java 虚拟机栈也是线程私有的,它的⽣命周期和线程相同,描述的是 Jav ...

  7. 深入理解JVM虚拟机 - 自我编译JDK

    深入理解JVM虚拟机 - 自我编译JDK <深入理解JVM虚拟机>看过了好几遍了,对于编译一个JDK源码有很强的冲动.这里主要实战使用阿里云进行编译实战 为什么使用阿里云? 个人电脑奋斗四 ...

  8. 深入理解JVM虚拟机(二):垃圾回收机制

    谈起GC,应该是让Java程序员最激动的一项技术,我相信每个Java程序员都有探究GC本质的冲动!JVM垃圾回收机制对于了解对象的创建和对象的回收极为重要,是每个Java程序员必须掌握的技能. 本博客 ...

  9. 深入理解JVM(2)——GC算法与内存分配策略

    说起垃圾收集(Garbage Collection, GC),想必大家都不陌生,它是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行在JVM上的语言,如Sca ...

最新文章

  1. Spring官宣新家族成员:Spring Authorization Server!
  2. 国内自动驾驶战局如何?我对比了下华为大疆特斯拉百度等公司
  3. 服务器发送退出状态127,TCP正常建立和关闭的状态变化
  4. mysql设计的步骤_mysql笔记8_数据库设计步骤
  5. 【人脸识别】LFW数据集介绍
  6. mount nfs 经常出错信息总结(转)
  7. halcon-高速下载
  8. Funcode拍飞虫 C语言
  9. typecho添加html5视频播放器,DPlayer-Typecho视频播放插件
  10. kafka消费者报错:Consider using the new consumer by passing [bootstrap-server] instead of [zookeeper].
  11. JDK1.6支持TSL1.2协议
  12. JAVA javaweb JSP水果管理系统源码(水果进销存管理系统水果管理系统(水果进销存)
  13. 如何拿到9家大厂的前端校招offer
  14. Autoar之 CAN NM网络管理
  15. 数学建模国赛论文怎么写?
  16. 计算机基础知识(基础入门小白专属)九
  17. Computer Graphics Through OpenGL From Theory to Experiments - 学习笔记2 Tricks of the Trade opengl基础
  18. 图形学笔记(十八)光场、颜色和感知—— 光场相机(全光函数、光线和光场的定义)、可见光谱、谱功率密度、颜色的生物学基础、Tristimulus Theory、同色异谱、加色与减色系统、颜色空间SPD
  19. 北航3系 (自动化) 控制科学与工程 保研经历
  20. 电脑录制GIF动态图

热门文章

  1. 服务器架设笔记——打通MySQL和Apache
  2. 用python3实现指定目录下文件sha256及文件大小统计
  3. mysql实现sass_使用sass绘制三角形
  4. php遍历文件夹下文件内容_PHP遍历某文件夹下的文件与文件夹名
  5. 微服务项目用了几台服务器,微服务部署运维
  6. oracle表中怎么去重复,oracle去掉表重复数据
  7. mysql thread safe_Windows环境下完全手工配置Apache、MySQL和PHP(Thread Safe)
  8. impala 本年格式化时间_hive,hbase,impala之间的对比
  9. 一台支持vlan管理的交换机_关于交换机的VLAN技术你了解多少?
  10. 用java实现一个简易自动提款机