【JVM】HotSpot JVM内存管理和GC策略总结

标签: jvm hotspot jvm | 发表时间:2011-12-13 22:05 | 作者:
出处:http://www.iteye.com

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参数
参数 含义
-Xms 最小堆空间
-Xmx 最大堆空间
-Xmn 新生代空间
-Xss 线程栈空间
-XX:PermSize=xxx 永久代空间
-XX:MaxPermSize=xxx 最大永久代空间
-XX:SurviorRatio=xxx
代表eden:s0的比例
-XX:NewRatio=xx 新生代和旧生代的比例.
-XX:MaxTenuringThreshold。 在新生代最大存活次数

hotspot 内存垃圾回收策略总结

1.内存回收策略和常见概念

常见内存回收策略可以从以下几个维度来理解:

1.1 串行&并行
串行:单线程执行内存回收工作。十分简单,无需考虑同步等问题,但耗时较长,不适合多cpu。
并行:多线程并发进行回收工作。适合多CPU,效率高。
1.2 并发& stop the world
stop the world:jvm里的应用线程会挂起,只有垃圾回收线程在工作进行垃圾清理工作。简单,无需考虑回收不干净等问题。
并发:在垃圾回收的同时,应用也在跑。保证应用的响应时间。会存在回收不干净需要二次回收的情况。
1.3 压缩&非压缩&copy
压缩:在进行垃圾回收后,会通过滑动,把存活对象滑动到连续的空间里,清理碎片,保证剩余的空间是连续的。
非压缩:保留碎片,不进行压缩。

copy:将存活对象移到新空间,老空间全部释放。(需要较大的内存。)

 

一个垃圾回收算法,可以从上面几个维度来考虑和设计,而最终产生拥有不同特性适合不同场景的垃圾回收器。

2.HotSpot JVM的YGC&FGC

YGC :对新生代堆进行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 :识别哪些是存活的
Sweep : 识别垃圾,并回收
Compact :滑动活动对象并压缩到连续空间,碎片整理

 

串行垃圾回收器在jvm client模式下是默认启动的。参数 -XX:+UseSerialGC 可以设置垃圾回收策略为串行。

 

3.2并行垃圾回收器

主要以下特点:

充分利用CPU
吞吐量优先
和串行一样,不过是多线程执行,缩短了stop-the-world时间。
-server模式下默认的回收器。参数 -XX:+UseParallelGC 可以设置垃圾回收策略为并行。

 

3.3并行压缩收集器(Parallel Compacting Collector)

只对老生代适用,新生代仍旧和并行垃圾回收器一样。

其过程大概如下:

标记阶段 ,使用多线程对存在引用的对象进行并行标记。
分析阶段 ,GC对各个区域进行分析,GC认为,在经过上次GC后,越左边的区域,有引用的对象密度要远远大于右边的区域。所以就从左往右分析,当某个区域的密度达到一个值的时候,就认为这是一个临界区域,所以这个临界区域左边的区域,将不会进行压缩,而右边的区域,则会进行压缩。
压缩阶段 ,多各个需要压缩的区域进行并行压缩

 

参数-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.sun.com/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.bluedavy.com/?p=200

 

 

 



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [jvm hotspot jvm] 推荐:

HotSpot JVM 触发 OutOfMemoryError 参数

- - 编程语言 - ITeye博客
正好今天是愚人节,就来说点骗子的东西吧~. 时不时的我就会听见有人抱怨说,他的HotSpot JVM不停的在垃圾回收,可是每次回收完后堆却还是满的. 当他们发现这是因为JVM的内存已经不够了之后,通常会问这么个问题,为什么JVM不抛一个OutOfMemoryError(OOME)呢. 毕竟来说,由于内存不足,我的程序都已经没法继续跑了,对吧.

[译] HotSpot JVM 内存管理

- - IT瘾-dev
HotSpot JVM 内存管理. 更新时间:2018-03-28. 关于 JVM 内存管理或者说垃圾收集,大家可能看过很多的文章了,笔者准备给大家总结下. 这算是系列的第一篇,接下来一段时间会持续更新. 本文主要是翻译《 Memory Management in the Java HotSpot Virtual Machine》白皮书的前四章内容,这是 2006 的老文章了,当年发布这篇文章的还是 Sun Microsystems,以后应该会越来越少人记得这家曾经无比伟大的公司了.

【JVM】HotSpot JVM内存管理和GC策略总结

- - ITeye博客
JVM的相关知识是学习java高级特性必须要去深入学习的. 平时也有一些学习和实践,不过总结比较少. 今天有时间总结一下最基础的内存模型和GC策略的知识,在此记录一下. hotspot jvm内存模型. hotspot的内存模型很多地方都有类似总结,我也简单总结了一下,大概可以用下图表示:. 1.线程栈:线程创建是会为每个线程创建一个线程栈,线程栈里面会为每个方法调用创建一个栈帧.

JVM研究

- - 开源软件 - ITeye博客
每天接客户的电话都是战战兢兢的,生怕再出什么幺蛾子了. 我想Java做的久一点的都有这样的经历,那这些问题的最终根结是在哪呢. JVM全称是Java Virtual Machine,Java虚拟机,也就是在计算机上再虚拟一个计算机,这和我们使用 VMWare不一样,那个虚拟的东西你是可以看到的,这个JVM你是看不到的,它存在内存中.

jvm调优

- - 互联网 - ITeye博客
printf "%x\n" 21742  找到耗时最长的进程. jstack pid | grep 54ee  定位某个类的方法. jstack 10535|grep -A 10 2a1d (最后十行). jmap 查询pid 内存线程. 附:TOP命令中需要关注的值:. (1)load average:此值反映了任务队列的平均长度;如果此值超过了CPU数量,则表示当前CPU数量不足以处理任务,负载过高.

学习JVM的References

- LightingMan - 淘宝JAVA中间件团队博客
本blog中列举了我学习JVM的references,会不断的更新,为了避免版权问题,就不在blog上提供references的下载了,感兴趣的同学可自行下载或购买,:). |— [ Hotspot GC论文 ]. |— [ 其他JVM GC ]. |— Linux内核源代码情景分析. |— Linux 内核中断内幕.

深入理解JVM

- 小伟 - ITeye论坛最新讨论
1   Java技术与Java虚拟机. 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成: Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API). 图1   Java四个方面的关系. 运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件).

jvm垃圾回收

- Cano - 淘宝共享数据平台 tbdata.org
在jvm中堆空间划分为三个代:年轻代(Young Generation)、年老代(Old Generation)和永久代(Permanent Generation). 年轻代和年老代是存储动态产生的对象. 永久带主要是存储的是java的类信息,包括解析得到的方法、属性、字段等等. 我们这里讨论的垃圾回收主要是针对年轻代和年老代.

JVM内存分配

- - 移动开发 - ITeye博客
计算机内存,它算是CPU与计算机打交道最频繁的区域,所有数据都是先经过硬盘至内存,然后由CPU再从内存中获取数据进行处理,又将数据保存到内存,通过分页或分片技术将内存中的数据再flush至硬盘. 那JVM的内存结构到底是如何呢. JVM做为一个运行在操作系统上,但又独立于os运行的平台,它的内存至少应该包括象寄存器、堆栈等区域.

Azul开源Zing Jvm

- - InfoQ cn
4月末,继Zing 5.2 之后,. Azul Systems宣布他们将无停顿(pauseless )的 Zing JVM提供给开源软件开发者和项目,以供开发和测试. Azul Systems 工程部副总裁和合作创始人Shyam Pillalamarri向InfoQ说明道:. 我们的部署很大一部分基于开源组件,所以我们认为:“假设我们不能将一些有价值的东西免费提供给开源项目贡献者,他们将一直受限于从Java虚拟机(JVM)视角所看到的内容”,他们将不会考虑额外的用例,或者选择其他能解决了所有内存或扩展性问题、类似Zing的系统.