JVM学习总结四——内存分配策略
之前几篇我们介绍了jvm的内存模型以及垃圾回收机制,而本篇我们将介绍几个JVM中对象在分配内存是应该遵循的策略。毕竟,想要去优化程序,不仅要考虑垃圾回收的过程,还要从对象内存分配的角度减少gc的代价。
一、gc日志格式
在这里先介绍一下gc日志的格式,分析gc日志是了解gc过程最直接的方式。对于大量的日志分析,直接查看日志文件当然不方便,我们一般会使用日志分析工具,后边会有介绍,但是对于简短的日志(如十几条),一般直接查看就行了。开启日志输出的JVM参数如下:
-XX:+PrintGCDetails //打印gc日志
-XX:+PrintGCDateStamps //打印时间
-Xloggc:gc.log //输出路径
对应的日志输出格式如下(采用不同参数或不同虚拟机可能不同,但大同小异):
2014-03-09T18:10:47.639+0800: 36.408: [GC 36.408: [DefNew: 35072K->4352K(39424K), 0.0108988 secs] 75088K->45293K(126848K), 0.0109419 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
2014-03-09T18:10:48.562+0800: 37.331: [Full GC 37.343: [Tenured: 40941K->42890K(87424K), 0.1340821 secs] 62210K->42890K(126848K), [Perm : 36863K->36863K(36864K)], 0.1341736 secs] [Times: user=0.13 sys=0.00, real=0.15 secs]
35072K->4352K(39424K):gc前使用内存大小->gc后使用大小(该区域总大小)
2014-03-09T18:10:47.639+0800: gc时间
36.408: gc耗时
GC 36.408: 表示停顿类型和停顿时间,如果是Full表示gc是Stop-The-World的
DefNew: Tenured: Perm : gc发生的区域,DefNew年轻代;Tenured年老代;Perm永久代
Times: user=0.13 sys=0.00, real=0.15 secs user:用户态耗时;sys:内核态耗时;real:gc从开始到结束消耗的Wall Clock Time耗时(墙钟时间,名字好怪,包括各种非运算的等待耗时和cpu耗时)
二、内存分配策略
1、对象优先在Eden分配
新的对象大多数情况下在Eden去分配,这样在Eden区域没有足够空间时,JVM会首先进行Minor Gc,仅对Eden进行gc,并将符合条件的对象移至年老代。这样如果Eden在gc后满足新对象的空间需求,则能避免进行Full GC。
2、大对象直接进入年老代
这一点十分好理解,多数情况下大对象的生命周期是相对较长的,而大对象如果分配在Eden,不仅占用大量空间,触发gc,还可能会在Eden区/两个Survivor区之间来回复制,十分耗费资源。因此,多数时候对于大对象,应该直接分配至年老代,开始用-XX:PertenureSizeThreshold参数指定直接分配年老代的大小。
3、长期存活的对象进入年老代
一般经过多次Minor GC而不死的对象,继续活下去的可能新更大,因此应该进入年老代。为了判断哪些对象长期存活,虚拟机给每个对象都定义了一个Age计数器,没经历一次Minor GC就+1,可以通过-XX:MaxTenuringThreshold的值来决定age达到多少时进入年老代。
4、动态对象年龄判断
为了能更好地适应不同程序的内存状况,虚拟机并不总是要求对象的年龄必须达到MaxTenuringThreshold 才能晋升老年代,如果在 Survivor 空间中相同年龄所有对象大小的总和大于Survivor 空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold 中要求的年龄。
5、空间分配担保
在发生 Minor GC 时,虚拟机会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间大小,如果大于,则改为直接进行一次 Full GC。如果小于,则查看 HandlePromotionFailure 设置是否允许担保失败;如果允许,那只会进行 Minor GC;如果不允许,则也要改为进行一次 Full GC。 前面提到过,新生代使用复制收集算法,但为了内存利用率,只使用其中一个 Survivor 空间来作为轮换备份,因此当出现大量对象在 Minor GC 后仍然存活的情况时(最极端就是内存回收后新生代中所有对象都存活),就需要老年代进行分配担保,让 Survivor 无法容纳的对象直接进入老年代。与生活中的贷款担保类似,老年代要进行这样的担保,前提是老年代本身还有容纳这些对象的剩余空间,一共有多少对象会活下来,在实际完成内存回收之前是无法明确知道的,所以只好取之前每一次回收晋升到老年代对象容量的平均大小值作为经验值,与老年代的剩余空间进行比较,决定是否进行 Full GC来让老年代腾出更多空间。
本篇介绍完毕,下一篇将介绍JVM监控相关的一些工具。
JVM学习总结四——内存分配策略的更多相关文章
- 深入理解JVM(5)——垃圾收集和内存分配策略
1.垃圾收集对象 垃圾收集主要是针对堆和方法区进行. 程序计数器.虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后也会消失,因此不需要对这三个区域进行垃圾回收. 哪 ...
- jvm垃圾收集器与内存分配策略
一.垃圾回收 1.对象是否已经变为垃圾 1.1.引用计数法:给对象添加一个引用计数器,每当有地方引用它时,计数器就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就是不可能再被使用的. 这 ...
- [jvm]垃圾回收与内存分配策略
一.垃圾回收算法 概述 JVM中,当创建的对象不再被使用的时候,此时我们认为他是无用的“垃圾”:在现代主流的商用jvm中,都是通过可达性分析来判断对象是否存活的.这个算法的基本思想是通过一系列“GCR ...
- JVM垃圾收集器与内存分配策略(一)
在前面的Java自动内存管理机制(上)和Java自动内存管理机制(下)中介绍了关于JVM的一些基础知识,包括运行时数据区域划分和一些简单的参数配置,而其中也谈到了GC,但是没有深入了解,所以这里开始简 ...
- 深入理解JVM - 垃圾收集器与内存分配策略 - 第三章
引用计数算法——判断对象是否存活的算法 很多教科书判断对象是否存活的算法是这样的:给对象添加一个引用计数器,每当一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象 ...
- jvm垃圾回收器与内存分配策略
一.判断对象存活的算法 1.引用计数算法 (1)概念:给对象中添加一个引用计数器每当有一个地方引用它时,计数器值加1:当引用失效时,计数器就减1:任何时刻计数器为0的对象就是不可能再被使用的. (2) ...
- jvm系列(二)jvm垃圾收集器与内存分配策略
众所周知,在java语言中,内存分配和回收是由jvm自动管理的.因此内存的分配和回收也是jvm三大功能之一.垃圾收集器(GC)需要完成三件事情: 哪些内存需要回收? 什么时候进行回收? 如何回收? 本 ...
- JVM·垃圾收集器与内存分配策略之垃圾回收算法!
1.垃圾回收算法 1.1.标记-清除算法(Mark-Sweep): 过程分为“标记”和“清除”两个过程.先将所有需要回收的目标统一标记,然后再统一清除. ...
- JVM·垃圾收集器与内存分配策略之对象是否可被回收!
1.判断对象已经死去/不再被引用. 1.1.引用计数算法:给对象添加引用计数器,有个地方引用就+1,引用失效就-1.任何时刻,引用为0,即判断对象死亡. 1.1.1.优点:实现 ...
随机推荐
- 根据文字返回Label高度
NSString分类 @implementation NSString (stringSize) //计算文字显示的所需要的size -(CGSize)sizeWithFont:(UIFont *)f ...
- linux下的tomcat自动退出的问题
1,环境:mysql+tomcat+linux 2,发现问题:连接池断开连接 No operations allowed after connection closed 连接池断开了,再进行连接就报错 ...
- hbase查询,scan详解
一.shell 查询 hbase 查询相当简单,提供了get和scan两种方式,也不存在多表联合查询的问题.复杂查询需通过hive创建相应外部表,用sql语句自动生成mapreduce进行.但是这种简 ...
- how to extract and decrypt WeChat EnMicromsg.db on Android phone
One of my friend came to me with an Android phone. She saild somehting wrong with the hardware of he ...
- Android IOS WebRTC 音视频开发总结(三二)-- WebRTC项目开发建议
本文主要介绍WEBRTC开发过程中的一些现象,文章来自博客园RTC.Blacker,支持原创,欢迎关注微信公众号blacker,更多详见www.rtc.help 随着移动互联网和智能硬件的快速发展,音 ...
- MySQL的存储引擎整理
01.MyISAM MySQL 5.0 以前的默认存储引擎.MyISAM 不支持事务.也不支持外键,其优势是访问的速度快,对事务完整性没有要求或者以SELECT.INSERT 为主的应用基本上都可以使 ...
- SQL Server编程(05)游标
在关系数据库中,我们对于查询的思考是面向集合的.而游标打破了这一规则,游标使得我们思考方式变为逐行进行.对于类C的开发人员来着,这样的思考方式会更加舒服. 正常面向集合的思维方式是: 而对于游标来说: ...
- tomcat学习笔记1
tomcat是一个开源软件,是由java语言编写的,它工作的话需要运行在jvm虚拟机中,说到jvm不得不说下java这个大名鼎鼎的编程 语言了 java这个编程语言最优秀的特点要数write once ...
- ubuntu 12.04 LTS(64位)安装apache2
在网上找了很多文章,说法不一,不知道应该用哪种方法,后来想就用其中最简单的吧,装不好再卸了重装, 然后就...装上了,用的是tar包源码安装,下面是步骤 1.去官网下载apache2.2.25源码包, ...
- 对phpcms中{L('news')}的讲解
直切话题 对于phpcms分M,C,A,那么现在要讲解的L是跟着M走的,每个M在languages中都有一个.lang.php文件,如Mcontent,就有一个content.lang.php,找到对 ...