之前几篇我们介绍了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监控相关的一些工具。

转载于:https://www.cnblogs.com/good-temper/p/3590411.html

JVM学习总结四——内存分配策略相关推荐

  1. jvm垃圾收集器与内存分配策略

    2019独角兽企业重金招聘Python工程师标准>>> 垃圾收集器与内存分配策略: 以下参考周志明的<<深入理解jvm高级特性与最佳实践>>. 判断对象是否存 ...

  2. JVM:垃圾收集器与内存分配策略

    垃圾收集器与内存分配策略 1.对象已死吗 1).引用计数算法 引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就 ...

  3. java eden分配参数,JVM垃圾收集器与内存分配策略,

    垃圾收集器与内存分配策略 对象存活判断 引用计数算法 给对象添加一个计数器,每有一个引用+1,当引用失效-1,若为0则不在被使用. 可达性分析算法 对象是否可到达GC roots 或者说GC root ...

  4. JVM垃圾收集器与内存分配策略学习总结

    方法区: 1.线程共享 2.储存类信息,常量,静态变量,编译器编译后的代码 3.非堆(别名)用于区分Java堆 4.不需要连续的内存 5.可以固定或可扩张 6.选择不实现垃圾回收//这个区域很少进行垃 ...

  5. 20200405——java之jvm 垃圾回收器和内存分配策略 二

    什么叫GC Garbage Collection 什么内存区域需要GC 共享区的都要被回收比如堆区以及方法区. 在进行内存回收之前要做的事情就是判断那些对象是'死'的,哪些是'活'的.常用方法有两种 ...

  6. [JVM] 垃圾收集器与内存分配策略

    目录 简介 哪些内存需要回收 引用计数算法 可达性分析 再次谈引用 生存和死亡 简介 GC(Carbage Coolection),需要完成的3件事情 : 哪些内存需要回收 什么时候回收 如何回收 程 ...

  7. JVM学习笔记之-堆,年轻代与老年代,对象分配过程,Minor GC、Major GC、Full GC,堆内存大小与OOM,堆空间分代,内存分配策略,对象分配内存,小结堆空间,逃逸分析,常用调优工具

    堆的核心概述 概述 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域.Java堆区在JVM 启动的时候即被创建,其空间大小也就确定了.是JVM管理的最大一块内存空间. 堆内存的大小是可 ...

  8. jvm(3)-垃圾收集器与内存分配策略

    [0]README 0.1)本文部分文字转自:深入理解jvm,旨在学习 垃圾收集器与内存分配策略 的基础知识: [1]垃圾回收概述 1)GC(Garbage Collection)需要完成的3件事情: ...

  9. JVM内存管理:深入垃圾收集器与内存分配策略

    Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...

  10. 【转】JVM内存管理:深入垃圾收集器与内存分配策略

    2019独角兽企业重金招聘Python工程师标准>>> Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收 ...

最新文章

  1. 图像处理 100 问!!
  2. linux程序已经在后台运行冻结了_Linux 让程序在后台执行
  3. 台阶问题(洛谷P1192题题解,Java语言描述)
  4. 洛谷 1313 计算系数——水题
  5. 主动土工围栏行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  6. ArcGIS Server 10.1发布数据源为ArcSDE(直连)的MXD【转】
  7. Spring Cloud Alibaba Sentinel之流控规则篇
  8. linux centos安装wine qq,ubuntu安装wine QQ
  9. 使用SVG画一个罗盘
  10. 【win10 cuda pytorch】从无到有配置gpu运算pytorch的极度详细完整方法教程(包括各种坑),网上其他方法基本可行性不高
  11. ABAP ALV DEMO示例源码
  12. Python3 网络爬虫:视频下载,那些事儿!
  13. pepe:从Pastebin收集邮件地址的信息
  14. 2022 腾讯社招Golang后端面试经验分享
  15. 2022年第七届数维杯大学生数学建模挑战赛报名通知
  16. 在ArcMap中画一条彩虹颜色的路
  17. 如何在星巴克点一杯好喝的咖啡
  18. Nimbus 社区AMA-第6期
  19. VMWare 15安装以及创建Ubuntu虚拟机
  20. java设计模式之代理模式详解

热门文章

  1. ajax基本概念,方法
  2. Exchange server 2010批量建用户及通讯地址簿更新
  3. javascript 光标位置
  4. 解读TIME_WAIT--你在网上看到的大多数帖子可能都是错误的
  5. 常见iPhone设备尺寸及分辨率(持续更新)
  6. hdu5187 奇怪题
  7. UIWebView关于XMLHttpRequest的内存泄漏
  8. 华为、海康--硬件工程师面经
  9. python之IO多路复用
  10. java新手笔记18 类比较