Java垃圾收集器和内存分配策略

JVM垃圾收集和内存回收

一、常用的判断对象存活算法

要进行垃圾回收,首先要做的一件事就是判断哪些对象是垃圾,哪些对象又是可用的。下面是两种常见的垃圾判断算法。
  1. 引用计数器算法
    为对象添加一个引用计数器,当有引用地方引用到它时,计算器就加一,当一个引用失效的时候,计数器就减一。
    优点:实现简单,高效
    缺点:很难解决对象之间循环引用的问题
  2. 根搜索算法
    根据一系列GC ROOT的引用链来判断哪些对象已经失效。(不在引用链里面的对象都判为已失效)
    Java中,可以作用GC ROOT的对象包括以下:
  • 虚拟机栈中引用的对象(栈帧的本地变量表)。
  • 方法去的静态属性引用的对象
  • 方法区的常量引用的对象
  • 本地方法栈中JNI引用的对象

二、根搜索算法

这里重点介绍一下根搜索算法,因为主流的HotSpot虚拟机和大多JVM虚拟机用的都是这一算法。
  • 关于finalize()方法
    被根搜索算法标记不可用的对象,其实不会马上死亡。虚拟机会给一次自我救赎的机会。这个机会就在finalize里面。如果对象覆盖了finalize方法,JVM第一次发现对象不可用的时候,会先执行finalize方法。如果对象在finalize方法中重新与某个对象关联起来,就可以逃过死亡。如果JVM下一次GC的时候如果发现该对象还是不可用,就会让其真正死亡。
    需要注意的是,每个对象只有一次救赎机会,也就是只会执行一次ifinalize方法。也就是如果执行完finalize方法后,该对象又被GC发现不可用了,这时是不会再有救赎的机会了。同时也不推荐用finalize()方法来防止对象被回收
    oopMap: 让JVM知道哪些地方存放着对象引用。
    safePoint: 代码进入安全点后才会执行GC。Safepoint的选定既不能太少以致于让GC等待时间太长,也不能过于频繁以致于过分增大运行时的负荷。所以,安全点的选定基本上是以程序“是否具有让程序长时间执行的特征”为标准进行选定的。safePoint的选择
  • 循环的末尾 (防止大循环的时候一直不进入safepoint,而其他线程在等待它进入safepoint)
  • 方法返回前
  • 调用方法的call之后
  • 抛出异常的位置

三、垃圾回收算法

  1. 标记-清除算法
    先把所有不可用的内存块标记一下,最后统一清除。主要两个缺点:
  • 标记和清除的过程效率都不太高
  • 会产生内存碎片,等到有对象需要分配较大内存但是又没有这么大的连续内存时,不得不提前触发一次垃圾收集动作。
  1. 复制算法
    复制算法解决了效率和内存碎片的问题。它的理念内存分为两块,内存分配时只使用其中一块,之后GC时将可用对象复制到另一块内存中,接着将原来那个内存块的对象全部清除掉。
    这种方法简单粗暴,效率很高。但是却严重浪费了内存空间。
    现代商业虚拟机一般都采用复制算法来回收新生代对象。因为新生代大多都是朝生夕死,经过一次GC后存活的对象非常少,所以可以将内存分为8:1:1(Eden:survive:survive)。当执行GC的时候,直接查看Eden区和其中一块已经分配对象的survive区,然后将可用对象都复制到剩下的那块还没survive区中。这样内存使用率就高达90%了。(真正使用的内存时8+1)。
    另外,当10%的内存空间不够分配存活对象时,JVM会启动担保机制,将老生代的内存空间预支出来使用。
  2. 标记-整理算法
    复制算法在对象存活率很高的情况,效率会变低。所以不适合用当老生代的回收算法。于是有人提出了标记整理算法。思路就是将可用的对象都向一端移动,最后清除端边界以外的内存即可。
  3. 分代算法
    现在JVM虚拟机一般都根据新生代和老生代的特点分别使用不同的回收算法。新生代生存率低,所以使用复制算法。老生代生存率高,所以使用标记-清除或者标记-整理算法。

四、垃圾收集器

JVM垃圾收集器.png
  1. Serial 收集器
    这是一款比较老的收集器。由于是单线程处理,所以GC的时候停顿明显。jdk1.3.1这个收集器之前是唯一的选择。
    Serial对新生代对象(new)采用的是复制算法。老生代对象采用的是标记-整理算法。
  2. ParNew 收集器
    其实就是Serial的多线程版本。其他和Serial都差不多。
    除了Serial收集器外,它只能和CMS配合使用。
  3. Parallel Scavenge 收集器
    采用复制算法,并行的多线程收集器。
    特点就是可以人为的控制吞吐量。吞吐量就是真正代码执行时间和CPU消耗的总时间的比值。比如虚拟机在CPU上总共消耗了100分钟,GC花了1分钟。那吞吐量就是99%。可以根据下面3个参数来控制吞吐量:
    -XX:MaxGCPauseMillis 最大GC停顿时间(毫秒)。(也不要以为越小就越好)
    -XX:GCTimeRatio 直接设置吞吐量大小,范围0-100%
    -XX:+UseAdaptiveSizePolicy 当这个参数打开之后,就不需要手工指定新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象年龄(-XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量,这种调节方式称为GC自适应的调节策略(GC Ergonomics)。
  4. Serial Old 收集器
    Serial 收集器的老生代收集器。用标记-整理算法。这个收集器的主要意义是在client模式下使用。另外,它还有两大用途。
  • 与Parallel Scavenge搭配使用
  • 作为CMS的后备预案,当并发收集发送 Curruent Mode Failure的时候使用。
  1. Parallel Old 收集器
    Parallel的老生代收集器。采用标记-整理算法。一般与Parallel Scavenge搭配使用。
  2. CMS 收集器
    这是一款并发低停顿收集器。它的目标就是尽可能的减少GC造成的时间停顿。所以比较适合对web应用这种交互式应用。
    采用的是标记-清除算法。涉及的内容有点多,就不详细介绍。读者可自行百度或者查看以下链接。
    JVM实用参数(七)CMS收集器
  3. G1收集器
    G1收集器是收集器技术发展的最前沿结果。刚发布的JDK9已经将它作为默认垃圾收集器。
    采用标记-整理算法。深入理解JVM G1收集器
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354

推荐阅读更多精彩内容