`
suhuanzheng7784877
  • 浏览: 698464 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
Ff8d036b-05a9-33b5-828a-2633bb68b7e6
读金庸故事,品程序人生
浏览量:47587
社区版块
存档分类
最新评论

关于JVM内存回收算法的补充

    博客分类:
  • JVM
阅读更多

 

1.       再说JVM的分代回收策略

 

HotSpot的垃圾回收机制采用分代回收,堆分为年轻代和老年代,非堆就是持久带。面对不同的代,采用不同的回收策略。

 

而年轻代又可以分为1Eden2Survivor。对于Eden,大多数对象都是先在此区域开辟空间,存储年轻对象的实例数据。Eden相对于Old带,空间是比较小的。所以对象数据不断地在此开辟空间,Eden不够了,年轻代发生了回收。放置(稍后会说怎么放置)到S1或者S2S1或者S2不够放了,直接放到Old带。根据年轻代的特点,空间小,发生回收事件频率较高,那么就采用标记-复制的算法将Eden中的对象实例数据克隆到S1或者S2或者直接克隆到Old带。标记-复制算法优点是:快速、节省内存碎片。缺点是:内存消耗的空间需要变为原来的50%,另一块空间作为复制的目标。

 

老年代因为空间比较大,存储的对象又是比较长寿的对象,所以采用标记-整理或者也称作标记-压缩算法。这样不必开辟另外50%的空间用于复制目标,也不用担心这个较为辽阔的内存空间产生占用碎片的问题。缺点就是又标记、又压缩的。对于Old带比较费时间。

 

持久带虽然资料上没有明说,但是根据持久带的作用和特点以及触发该区回收的情景可以推算,持久带采用的回收算法应该是标记-整理/压缩算法。

 

JVM内存回收只要是针对这3个区域来说的。像NIO的直接文件内存读取,使用的是直接内存,只有出发了FullGC方能回收该区域!JNI调用本地库,本地代码所消耗的内存需要操作系统额外开辟内存。

 

2.       7大回收器的描述

 

先来看7个回收器的描述

 

======新生代的回收策略======采用标记-复制算法。

 

串行回收器:完全单线程的回收内存区域的不可达对象。串行回收过程中,所有程序都得停下来。直到串行回收过程执行完毕,用户的程序才可以继续进行。对于现在多核CPU的机器来说,这个串行的回收策略,优势越来越不明显。可用于C/S系统的客户端程序的回收器策略。

 

并行回收器:为了弥补串行回收器的不足,出现了并行回收器。多线程的方式进行回收。原理相当于多线程版本的串行回收器。利用CPU的多核优势分多个线程VS多个区域对内存进行回收而已。

 

吞吐量优先回收器:与多线程并行收集器的区别在于以吞吐量有限,保证用户运行代码的时间与内存回收的时间比,比重较大。让更多的时间去执行用户的代码。

 

======老年代的回收策略======采用标记-整理算法或者标记-清除。

 

串行老年版回收器:老年版串行回收。采用标记-整理。

 

吞吐量有限老年版回收器:吞吐量优先回收器老年版本,主要是为了将就年轻代的吞吐量优先回收器,在多线程,标记-整理算法的前提下,更保证了高吞吐量。

 

并发回收器:CMS回收器。用户的程序与垃圾回收标记程序可以同时运行。此所谓并行。短暂的停顿主要出现在标记上过程(细节是:初始标记、重新标记)。这里要声明一点,为了达到并发性。这里算法并不是使用标记-整理、而是逻辑最简单的标记-清除算法,有可能会造成老年代的内存碎片。不过可以通过别的方式进行弥补,比如标记-清除Full-GC后可以再进行一次标记-整理\压缩,避免内存的碎片过多。

 

======无论新老==============

 

新一代智能回收器:职能回收器。通过前期的回收统计、算法结果、有效地逃逸分析。来决定动态回收策略。(商业版本的JDK?到底免费不?费解?)

 

3.       算法组合以及应用场景描述

 

我们来看看新老带回收器的组合。

 

新生代+老年代组合如下:

 

1):串行回收器+串行回收器

 

使用JVM启动参数UseSerialGC启动此配置,主要场景用于单机版系统的启动配置,而且多用于老式的单核CPU的机器上。一旦遇到回收,用户自己的程序停顿时间会有比较明显的感觉。这个是JVM-Client工作模式的默认配置。

 

2):串行回收器+并行吞吐量回收器

 

JVM没有此搭配,从老年代并行吞吐量回收器的特点来说。并行吞吐量回收器出现的目的是为了让整个回收过程体现“吞吐量优先”的原则。而串行回收器作为新生代,而新生代回收的频率又是最大的。每次新生代回收,CPU都要为回收程序服务,用户程序都需要暂时停止。“吞吐量优先”的名称,是在名不副实。所以,JVM根本就没将这2个回收器配合使用。

 

3):串行回收器+并发回收器

 

原则上JVM规范指出串行回收器可以与并发回收器配合使用,但是在JVM启动参数中并没有具体的使用此配合的参数。原因待查……

 

4):并行回收器+串行回收器

 

使用启动参数UseParNewGC参数,可以使用此组合。一般情况下是在频率较高的年轻代不想消耗太多的时间,采用多线程的方式。在老年代并不使用多线程并行回收器,发生FullGC的时候,依然会阻塞很久。这种场景一般是年轻代的大小并不比老年代的大小小太多。而大家都知道一般在年轻代发生回收的频率是十分频繁的。发生在老年代的回收频率是不频繁的。如果应用大多数都是朝不保夕的对象,这种场景使用此配合。不过真的出现这种场景,您的应用程序可能在方法使用的时候多注意别创建无意义的多余对象。这个是JVM-Server工作模式的默认配置。

 

5):并行回收器+并行吞吐量回收器

 

JVM无此配置规范。

 

6):并行回收器+并发回收器

 

使用UseConcMarkSweepGC可实现此组合。这样确实是达到了一种几乎很快速的回收组合。新生代多线程标记-复制,老年代并发执行回收和用户线程同时运行。这样的组合对于老年代空间十分大,又是多核CPU的情况下,效果尤为明显。

 

对于互联网网站特别适用。但是在单核32位机器的硬性条件下,fullgc容易发生进程crash

 

7):并行吞吐量回收器+串行回收器

 

在老年代尚未出现并行吞吐量回收器的时代,这个并行吞吐量回收器只能和串行回收器配合。给人的感觉“吞吐量优先”有点名不副实。时间效率都被老年代给占用了。使用UseParallelGC可以使用这个配置玩玩。

 

8):并行吞吐量回收器+并行吞吐量回收器

 

使用UseParallelOldGC可以使用此组合。基本上这种组合适用于50%的应用场景。以用户的程序执行为优先。新生代、老年代都是以吞吐量优先的模式运行,随着程序运行时间越长,效果越明显。带来的唯一效率就是CPU、内存、内存IO读写需要付出更多的代价。不过对于用户程序运行比较敏感的系统,就不是问题了。

 

注:如果对于JVM的回收策略不是特别拿捏得当,使用这种组合,没准儿是最好的。

 

9):并行吞吐量回收器+并发回收器

 

JVM无此组合。



 
 

说明:

 

  • UseSerialGC:"Serial" + "Serial Old"
  • UseParNewGC:"ParNew" + "Serial Old"
  • UseConcMarkSweepGC:"ParNew" + "CMS" + "Serial Old". "CMS" is used most of the time to collect the tenured generation. "Serial Old" is used when a concurrent mode failure occurs.
  • UseParallelGC:"Parallel Scavenge" + "Serial Old"
  • UseParallelOldGC:"Parallel Scavenge" + "Parallel Old"

 

如果GC算法参数搭配不合理,会出现类似错误:

 

写道

 

Conflicting collector combinations in option list; please refer to the release notes for the combinations allowed
Could not create the Java virtual machine.

 

 

  • 大小: 167.6 KB
分享到:
评论

相关推荐

    JVM系列-第1章-JVM与Java体系结构

    面试中,面试官经常会问一些 JVM 相关的问题,如垃圾回收算法、JIT 等。中高级程序员需要掌握 JVM 的知识,以便更好地调优程序和解决问题。最后,学习 JVM 也可以满足我们追求极客的精神,了解 JVM 的内部实现机制,...

    【Java毕业设计】zvm-jvm,使用java完成对jvm的设计,这个也是我的毕业设计的初稿.zip

    5. 内存管理:JVM的垃圾回收机制负责自动管理内存,包括对象的分配和释放。zvm-jvm需要模拟这个过程,可能包括引用计数、标记-清除、复制、标记-整理和分代等算法。 6. 方法调用与返回:JVM支持动态方法调用,包括...

    JAVA核心面试知识整理.pdf

    JVM内存区域是Java虚拟机运行时数据区的重要组成部分,包括程序计数器、虚拟机栈、本地方法栈、堆和方法区。 - 程序计数器:线程私有,用于指示当前线程所执行的字节码执行到了哪一行。 - 虚拟机栈:线程私有,...

    golang 50k 高阶面试题

    - 垃圾收集器(Garbage Collector,GC):负责回收垃圾对象的组件,是JVM内存管理的重要部分。 - 垃圾回收根(GC Root):在对象图中起始点,用于标记阶段查找活跃对象的集合。 面试者在准备面试时应该熟悉CMS的每...

    深入java虚拟机第二版随书光盘

    重点理解对象的创建、垃圾回收、内存泄漏等问题。 4. **垃圾收集**:Java的自动内存管理主要依赖垃圾收集,包括分代收集、标记-清除、复制、标记-整理和局部GC等算法。理解GC的工作原理和调优技巧,可以有效地避免...

    个人对JVM五大部分的总结(欢迎网友指点、补充、指出错误)

    新分配的对象先到新生代的Eden区,要是Eden放不下,就会触发Minor GC垃圾回收,新生代使用的GC算法为引用计数法,首先Eden中存活的对象(仍然有在程序运行中被引用,这个引用可能是Method方法区中的常量池存储的引用...

    Wws_Android_Interview

    分代回收算法 垃圾回收算法 类加载过程(双亲委托) 补充: JMM(Java内存结构模型) Android基础(三天1.25-27,参考第一行代码及官方文档) 四大组件 活动的作用,生命周期(典型场景下生命周期的调用顺序),...

    Java虚拟机

    第五部分探讨了Java实现高效并发的原理,包括JVM内存模型的结构和操作;原子性、可见性和有序性在Java内存模型中的体现;先行发生原则的规则和使用;线程在Java语言中的实现原理;虚拟机实现高效并发所做的一系列锁...

    张孝祥正在整理Java就业面试题大全0719.doc

    4. **JVM内存模型**:理解堆、栈、方法区、本地方法栈的划分及垃圾回收机制。面试中会询问如何进行内存调优,以及内存泄漏和内存溢出的问题。 5. **多线程**:线程的创建、同步、通信(如synchronized、wait/notify...

    java学习资料.zip

    通过这些资料,你可以了解类加载机制、内存模型、垃圾回收、性能优化等方面的知识,这对于解决程序运行效率和内存管理问题至关重要。 3. **网络编程**:尽管"网络"一词在描述中提及,但没有直接相关的文件。然而,...

    面试快餐几个图一目了然-临阵补仓.zip

    5. **JVM内存模型**:堆、栈、方法区、本地方法栈、运行时常量池的分布及垃圾回收原理。 6. **IO与NIO**:输入输出流的层次结构、缓冲区、字符编码等,以及非阻塞I/O的介绍。 7. **网络编程**:TCP/IP协议、Socket...

    java面试基础总结八股文.zip

    10. **JVM**:了解JVM内存模型(堆、栈、方法区、本地方法栈),类加载机制,垃圾回收算法,以及如何进行性能优化。 11. **多线程并发**:理解线程同步(锁、 volatile、synchronized关键字)、并发工具类...

    Java程序员经典书籍推荐

    5. **高级特性详解**:比如垃圾回收算法、JIT编译等,这些都是提升Java应用性能的关键因素。 此书不仅内容全面、深入浅出,而且作者还不断地更新和完善内容,使之始终保持最新的状态。尽管网络上有电子版资源可获取...

    Potato:阅读适用于Android采访的他妈的源代码-android source code

    [目录] 阅读面试的源代码计划 本项目逐步面试准备过程的...:JVM内存结构,Java内存模型(JMM),Java对象模型 :HashMap源码分析 :Java线程和并发知识总结 : 和并发结合总结 :java各种锁 安卓 交互:Android nati

Global site tag (gtag.js) - Google Analytics