2019独角兽企业重金招聘Python工程师标准>>>

一、写在前面

在正式进入故事之前,我们得先想几个问题,

1.你是出于什么目的要去了解这件事情?

2.天天讲垃圾收集,到底回收了哪些地方?

3.GC是通过什么方法回收的?回收了哪些东西?

在这里不会去写具体的垃圾收集具体技术实现细节,首先能力有限,其次涉及的东西太多了,把我自己的理解和心得写出来,希望有以上跟我一样疑问的朋友看完之后,能有所帮助,望各路大神批评指正。

第一个疑问:出于什么目的要去了解这件事情?

我只能说一切源自生活,不存在丁点自己跟自己过不去的情况,有这空闲时间,宁愿多在微信上多撩几个妹子更high, 因为在工作中太多的bug和时间耗在了排查内存溢出、内存泄露的情况,尽管这种情况不是经常出现,但出现这种情况的时候总是会耗费太多的精力去一遍遍的查找,分析,其次,第二个很大的原因是,当你的硬件配备已经最优、网络配备已经最优、其他外在条件都有最优,但实际仍然无法满足日益增大的系统性能要求时,很显然,最根基的这块垃圾收集就成了最后的问题瓶颈所在,治病除根。

第二个疑问:到底回收了哪些地方?

有了问题的引导,自然就引出了问题的解决办法,我们把组成jvm运行时内存的几个地方列出来分析分析,自然就有答案了。

程序计数器:生命周期随线程声明周期而定,线程结束,生命结束,随之结束之后GC自动回收。

本地方法栈:生命周期随线程声明周期而定,线程结束,生命结束,随之结束之后GC自动回收。

栈:生命周期随线程声明周期而定,线程结束,生命结束,随之结束之后GC自动回收。

以上三个片区可以理解为内存的分配和回收都有定数,不需要过多的去考虑垃圾回收问题。

————————————分隔符--------------------------------

方法区:由程序运行期间动态分配空间,自然而然垃圾回收也是动态的,需要考虑垃圾回收问题(此片区可以配置为不回收,也就是所谓的“永久带”,详细细节参见下文描述)。

堆:由程序运行期间动态分配空间,自然而然垃圾回收也是动态的,需要考虑垃圾回收问题。

由此可见,以上5个区都会存在GC回收情况,只是我们的关注重点是方法区、堆。

第三个疑问:通过什么方法回收的?回收了哪些东西?

通过第二个疑问我们知道,方法区和堆才是我们要关注的垃圾回收管理重点,那这两者区别是啥呢?在jvm那些事中我们可以了解到,两者都是被线程共享的内存区域部分,先来说说方法区, 方法区用于存放程序里面写的常量、静态变量、已被jvm加载的类信息,其实方法区可以看作是堆的逻辑部分区域,可参见java虚拟机规范中的定义,这块区域会在GC分代收集中纳入管理回收区域,只是实现方法区而已,那这样一想,我们需要关注的重点就成了堆部分。下面看一下堆得组成部分及回收条件方法等。

这里只列出核心部分,便于记忆。

1.回收的前提条件:堆里面放着几乎全部new出来的对象实例部分,在进行GC之前,要做的准备工作是GC得先判断哪些对象还活着,哪些对象已死,活的对象保留,死的对象回收清除。所以,这里就引出了一个前置问题,用什么样的方式方法去判定一个对象是活着的还是死的,就引入了一系列的判定算法,

1.1引用计数算法 (更细节的解释说明可搜寻相关资料)

定义:为每个对象设置一个引用计数器,每引用一次该计数器加1,每解除引用一次该计数器减一,当引用计数器为0时,证明该对象没有被引用,即可列入被回收的范围之内。

优点:实现简单,效率高。

缺点:存在循环引用无法释放问题,导致某些情况无法回收,如   a=b,b=a。

1.2可达性分析算法(有些称呼为根搜索算法)

定义:通过一些列被称为GC ROOT的对象作为最顶层的父亲节点,并将该节点作为起始点,开始往下搜索每一个分支节点的挂载对象,当一个对象,没有任何途径能连接到GC ROOT时,即可视为可以垃圾回收的对象,即使几个子节点之间有互相引用但是无任何途径连接到GC ROOT节点时,也视为可垃圾回收的对象。但是上述两种情况,GC并不一定能回收他们,以为里面还有一个特例,对象逃逸,所以,这里即使出现没有到GC ROOT的引用链条,也不会立即被回收,而是会做标记,后续会进行一些条件判定,核心部分对象的finalize方法部分。

堆得内存组成部分

为了便于更好的垃圾回收,将堆进行了分代,也可理解为对堆又进行了分区域划分,划分为了两部分,年轻代、老年代。  上面我们说方法区如果算是堆得逻辑部分的话,那也就是说方法区也可以看做是堆的一个逻辑组成部分,被很多人称为永久代。

年轻代:由一个Eden和两个Survivor区组成,E区和两个S区大小空间占比默认为8:1:1,每次使用E区和一个S区,另一块S区空闲,备用(复制算法),一般你new一个对象出来就是在年轻代上创建了,为什么是“一般”,因为如果当年轻代上没有足够的空间放你这个对象时,直接就把你扔到老年代上去了。这部分回垃圾回收时,采用复制算法,将E区和S区通过判定算法,将存活的对象一次性复制进备用的那块S区,同时清空E区和被使用的那个S区,来实现垃圾回收。

老年代:存放大对象,在年轻代多次回收都没有被回收的对象会进入老年代,老年代采用标记清除,标记整理的回收算法实现。

这里会引出一个问题,当进行垃圾回收时,你的应用到底应该处于一个什么样的状态呢?考虑这个问题是因为,进行着垃圾回收呢,如果应用一直在跑,那就有可能会出现有些对象明明在垃圾回收算法中已经标记为可回收了,还没等回收刚好在这个过程中又重新被其他对象所引用了,此时进行垃圾回收就会报错,所以,当垃圾回收事件进行时,出现了一件事,即stop the world世界停止了,意味着应用会停下来,并进入到GC执行过程中去,一旦该事件发生,除了GC自身所需的支撑线程外,其他线程都将停止工作,直到整个GC任务结束才继续才能恢复,这就很可怕了,试想一下,你开发了一个应用,小到几个人应用,大到每天面临数以万计、千万级别的访问使用量甚至更大,出现GC时,不能在用户所能忍受的范围之内处理好这件事情的话,将会是多么恐怖的一件事情,老板疯了。因此你必须了解GC这块的细节,并对其进行优化。

转载于:https://my.oschina.net/tianshibuzuoai/blog/1610911

对GC垃圾收集的一点整理相关推荐

  1. JDK5.0中JVM堆模型、GC垃圾收集详细解析 .

    前段时间在一个项目的性能测试中又发生了一次OOM(Out of swap sapce),情形和以前网店版的那次差不多,比上次更奇怪的是,此次搞了几天之后啥都没调整系统就自动好了,死活没法再重现之前的O ...

  2. gc垃圾收集器 与gc算法_GC解释:收集器概述

    gc垃圾收集器 与gc算法 当前版本的HotSpot JVM包括三种类型的垃圾收集器: –串行收集器 –并行收集器 –多数同时收集者 它们都是世代的,这意味着它们利用了堆的划分方式 . 垃圾收集器负责 ...

  3. JVM(3)之垃圾回收(GC垃圾收集器+垃圾回收算法+安全点+记忆集与卡表+并发可达性分析......)

    <深入理解java虚拟机>+宋红康老师+阳哥大厂面试题2总结整理 一.堆的结构组成 堆位于运行时数据区中是线程共享的.一个进程对应一个jvm实例.一个jvm实例对应一个运行时数据区.一个运 ...

  4. 对于微信小游戏JS开发的一点整理

    对于微信小游戏JS开发的一点整理 我像大家一样,遇到了不懂的喜欢在csdn上搜索解决问题,这篇文章参考了csdn上一些博主的文章,故标为转载,主要是参考博主:陈田田. tips 代码包大小上限为4MB ...

  5. 关于修改host的一点整理

    在和GFW玩耍的道路上尝试了挺多方法,这里仅对上不去的网站进行分析的方法和修改host的方法做一点整理总结,基本的方法和原理网上有很多教程,就不再赘述了,纯属小白的一点小小尝试. 网站被墙的三种状态 ...

  6. C#CAD二次开发学习 两条直线求交点的方法IntersectWith的一点整理

    求两条直线交点时可以使用IntersectWith方法,但对于我这种初学者有点摸不清该怎么使用. 直接上代码吧 [CommandMethod("GTest")]public sta ...

  7. JVM - 再聊GC垃圾收集算法及垃圾收集器

    文章目录 Pre 分代收集理论 常见的垃圾收集算法 标记-清除算法 标记-复制算法 标记-整理算法 垃圾收集器 Serial收集器 Parallel Scavenge收集器 [JDK8默认] ParN ...

  8. JVM—GC垃圾收集器

    目录 1.Serial 垃圾收集器(单线程.复制算法) 2.ParNew垃圾收集器(Serial+多线程) 3.Parallel Scavenge 收集器(多线程复制算法.高效) 4.SerialOl ...

  9. gc的原因 频繁full_Java性能优化要点之:GC垃圾回收知识点整理

    要掌握了GC垃圾回收的相关知识点,程序员在工作中就不用担心内存管理了,因为垃圾收集器会自动进行管理.本文为大家整理了GC垃圾回收的学习笔记,主要内容包括了判断回收条件,虚拟机频繁full GC的解决对 ...

最新文章

  1. ZOJ 38727(贪心)
  2. 解决了无法显示验证码的问题
  3. python sklearn 归一化_第3章 Sklearn概述
  4. redis源码笔记-adlist
  5. 研究生夏令营计算机题目,2017计算机学科夏令营上机考试-B编码字符串
  6. Python webdriver调用Chrome报错
  7. bzoj3124 [Sdoi2013]直径 直径+树形dp
  8. 飘刃 v0.0.10 首次发布,超快执行速度的 Vue 项目构建工具
  9. EasyRecovery14永久免费版密钥电脑硬盘恢复教程
  10. DSP2812入门3——硬件设计
  11. c#学习笔记之Application.DoEvents应用
  12. python平方上标怎么输出,plot绘图同样适用
  13. 移动平台动画设计的12个原则
  14. elasticsearch2.4.1+kibana4.6.1+mavel2.4.1
  15. POI - Excel 打印配置
  16. WMS系统运用波次拣货原理
  17. adobe dreamweaver cs5序列号
  18. WIN7任务栏里面无用的图标如何清除
  19. 科普 | 什么是稀疏默克尔树多值证明
  20. 游戏行业比影视行业哪个更有前景?来看数据说话!

热门文章

  1. 设计模式:模板方法(Template Method Pattern)
  2. Spring高级程序设计(Spring框架创始人倾情推荐的权威开发指南)
  3. IDEA工具创建项目并提交码云和一些基本使用
  4. Nginx实用指南V1 (连载之四:流行CMS博客rewrite写法)
  5. 设计模式 之 适配器模式
  6. 百度地图API详解之公交导航
  7. Binder机制(一)
  8. 几个常用的eclipse快捷键
  9. 解决Win8.1系统LYNC共享PPT提示“演示文稿遇到问题”
  10. dpkg and apt