JVM的相关知识是学习java高级特性必须要去深入学习的。平时也有一些学习和实践,不过总结比较少。 今天有时间总结一下最基础的内存模型和GC策略的知识,在此记录一下。
hotspot jvm内存模型1.内存模型hotspot的内存模型很多地方都有类似总结,我也简单总结了一下,大概可以用下图表示:
1.线程栈:线程创建是会为每个线程创建一个线程栈,线程栈里面会为每个方法调用创建一个栈帧。主要用于保存线程的当前运行状态。 2.堆:用于存放运行时中生成的新对像。会划分成新生代和老年代。新生代里面又划分成了eden区、存活1区和存活2区。 3.永久区:方法和常量区,用于存放方法字节码元数据和各种常量。
为什么堆会划分为新生代和老年代? 基本原理:对于大部分应用,常驻对象不多。因为大部分存活寿命不长,新生代和老年代的划分有利于区分对待和缩小垃圾回收范围。(Most allocated objects are not referenced (considered live) for long, that is, they die young. Few references from older to younger objects exist.) 2.内存相关启动参数内存相关常见jvm参数
hotspot 内存垃圾回收策略总结1.内存回收策略和常见概念常见内存回收策略可以从以下几个维度来理解: 1.1 串行&并行
copy:将存活对象移到新空间,老空间全部释放。(需要较大的内存。)
一个垃圾回收算法,可以从上面几个维度来考虑和设计,而最终产生拥有不同特性适合不同场景的垃圾回收器。 2.HotSpot JVM的YGC&FGCYGC :对新生代堆进行GC。频率比较高,因为大部分对象的存活寿命较短,在新生代里被回收。性能耗费较小。 FGC :全堆范围的GC。默认堆空间使用到达80%(可调整)的时候会触发FGC。以我们生产环境为例,一般比较少会触发FGC,有时10天或一周左右会有一次。 3.常见GC算法和jvm参数3.1.串行垃圾收集器 新生代和老生代因为结构划分不一样,其串行收集器算法也不一样 新生代串行收集器 采用stop the world策略,步骤大概是:先从eden区扫描,把存活的对象拷贝到to区,如果to区放不下的对象直接拷贝到old区。再从from区扫描存活对象,如果对象存活次数超过阀值的就移到老年区,其他的移到to区。做完之后from和to区概念互换(from和to只是运行时的概念,其实就对应存活1区和存活2区)。 图形的表示如下: 回收前:
回收后:
老生代串行收集器 老生代垃圾回收主要分为三个阶段 Mark-sweep-compact Mark
:识别哪些是存活的
串行垃圾回收器在jvm client模式下是默认启动的。参数 -XX:+UseSerialGC 可以设置垃圾回收策略为串行。
3.2并行垃圾回收器 主要以下特点: 充分利用CPU
3.3并行压缩收集器(Parallel Compacting Collector) 只对老生代适用,新生代仍旧和并行垃圾回收器一样。 其过程大概如下: 标记阶段
,使用多线程对存在引用的对象进行并行标记。
参数-XX:+UseParallelOldGC 可以设置老生代垃圾回收策略为并行压缩。 3.4 Concurrent Mark-Sweep (CMS) Collector 主要特点 仍旧是老生代适用。 减少停顿,以响应时间为优先。 只有标记和清除,不会进行会压缩。 初始标记和清除支持和应用程序并发执行,中间还是会有一re-mark需要stop the world。 参数-XX:+UseConcMarkSweepGC 可以设置老生代垃圾回收策略为CMS。 3.5 G1垃圾收集器 是在JDK7里支持的,用于取代CMS。具体具体见:http://docs.oracle.com/javase/7/docs/technotes/guides/vm/G1.html 总结本文的内容只是仅限于基础层面的的一些知识总结,更加深入的知识点还需要后续深入学习。 以下提供一些学习参考: memory management whitepaper : http://java./j2se/reference/whitepapers/memorymanagement_whitepaper.pdf JVM option:http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html 淘宝的blue davy的一个jmm分享: http://blog./?p=200 |
|