深入了解java虚拟机(JVM) 第七章 内存分配策略
理解了jvm内存分配策略不仅是程序性能调优的重要知识,还能够给养成自己一种良好的代码思路,一个程序的代码差异往往都是在这里体现出来的。
一、对象优先分配到Eden区域
一般来说,新创建的对象都会直接分配到Eden区域,如果Eden区域内存不够,JVM就会触发GC(垃圾回收),一般来说在JVM中有3种GC:
Minor GC:指发生在新生代的垃圾收集动作,非常频繁,速度较快。
Major GC:指发生在老年代的GC,出现Major GC,经常会伴随一次Minor GC,同时Minor GC也会引起Major GC,一般在GC日志中统称为GC,不频繁。
Full GC:指发生在老年代和新生代的GC,速度很慢,需要Stop The World。
所以在Eden区域中发生的GC就是Minor GC,在虚拟机中,可以设置Eden区域的大小从而调节Minor GC的频率,参数为:
-Xmx10240m -Xms10240m -Xmn5120m -XXSurvivorRatio=3
其中:
-Xmx:最大堆大小
-Xms:初始堆大小
-Xmn:年轻代大小
-XXSurvivorRatio:年轻代中Eden区与Survivor区的大小比值,即Eden区域内存/Survivor区域内存的值
二、大对象直接分配到老年代
那么多大的对象算是大对象呢?一般来说,这个定义大对象的值可以通过虚拟机的参数来设置:
-XX:PretenureSizeThreshold=XX
如果大于XX的对象就会直接分配到老年代, 为什么大对象要直接分配到老年代?
一般认为大对象为长字符串,存活较久,如果进入新生代,因为eden中的GC回收频率较高,大对象在进行对象标记算法时会影响到JVM的性能。
三、长期存活的对象进入老年代
这个应该很好理解,长期存活的对象证明该对象的引用频率较高,所以放入老年代中可以更好的提高eden中内存的大小。存活多久才算长期存活?
在JVM触发GC回收Eden区域后,还存活的对象就会复杂到Survivor区域整,该区域中有年龄存活计数器,设置年龄为1,对象在Survivor区每次经过一次Minor GC,年龄就加1,当年龄达到一定程度(默认15),就进入到老年代,
年龄可以通过虚拟机的参数来设置:
-XX:MaxTenuringThreshold
四、空间分配担保
所谓的空间分配担保是指:在新生代内存不够时即发生了Minor GC,向老年代借内存的情况就是空间分配担保。要验证如果老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小就会进行Minor GC,否则将进行Full GC,如果发生了Full GC将会大大降低程序性能,最简单的情况就是程序会出现非网络原因的卡顿。
五、动态对象年龄判断
对象的年龄到达了MaxTenuringThreshold可以进入老年代,同时,如果在survivor区中相同年龄所有对象大小的总和大于survivor区的一半,年龄大于等于该年龄的对象就可以直接进入老年代。无需等到MaxTenuringThreshold中要求的年龄。
六、逃逸分析与栈上分配
这个策略是在JVM栈中进行的。由于jvm栈内存是在方法独占区中,每一次程序运行完毕后,栈上的内存随着方法的执行来分配空间,且栈帧出栈时会消灭空间,因此不会进行GC回收。栈上分配后,JVM的性能会很快,所以在编写代码过程中,优先考虑栈上分配来写代码是个很好的代码习惯。
那么什么情况下,可以使用栈上分配,这就需要在对代码进行逃逸分析:我们要分析对象的作用域,如果一个对象的作用域在方法体内,那么这个对象就没有发生逃逸,没有发生逃逸的对象可以进行栈上分配。
关于逃逸分析更深入的理解,可以参考这篇博客:https://blog.csdn.net/w372426096/article/details/80938788
深入了解java虚拟机(JVM) 第七章 内存分配策略的更多相关文章
- 深入理解Java虚拟机:垃圾收集器与内存分配策略
目录 3.2 对象已死吗 判断一个对象是否可被回收 引用类型 finalize() 回收方法区 3.3. 垃圾收集算法 1.Mark-Sweep(标记-清除)算法 2.Copying(复制)算法 3. ...
- java虚拟机(六)--垃圾收集器和内存分配策略
目前没有完美的收集器,不同的厂商.版本的虚拟机提供的垃圾收集器会有很大的差别,用户根据自己应用特点和要求组合出各个年代所使用 的收集器.基于jdk1.7Update14之后的虚拟机. HotSpot的 ...
- 深入理解Java虚拟机笔记——垃圾收集器与内存分配策略
目录 判断对象是否死亡 引用计数器算法 可达性分析算法 各种引用 回收方法区 垃圾收集算法 标记-清除算法 复制算法 标记-整理算法 分代收集算法 HotSpot算法实现 枚举根节点 GC停顿(Sto ...
- 深入理解Java虚拟机之读书笔记三 内存分配策略
一般的内存分配是指堆上的分配,但也可能经过JIT编译后被拆散为标量类型并间接地在栈上分配.对象主要分配在新生代的Eden区上,如果启动了本地线程分配缓冲,将按线程优先在TLAB上分配,少数情况下直接分 ...
- 深入JAVA虚拟机笔记-垃圾收集器与内存分配策略
第三章:垃圾收集器与内存分配 问题:1.哪些内存需要回收 2.什么时候回收 3.怎么回收 回收方法区:
- 《深入理解Java虚拟机》——垃圾收集器与内存分配策略
GC需要完成: 哪些内存需要回收 什么时候回收 如何回收 如何确定对象不再使用 引用计数算法 给对象添加一个引用计数器,当有一个地方引用它时,计数器值进行加1操作:当引用失效时,计数器值进行减1操作: ...
- 深入理解java虚拟机(3)垃圾收集器与内存分配策略
一.根搜索算法: (1)定义:通过一系列名为"GC Roots"的对象作为起点,从这些起点开始向下搜索,搜索走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连的时 ...
- 【java虚拟机序列】java中的垃圾回收与内存分配策略
在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃 ...
- 《深入理解Java虚拟机》学习笔记之内存分配
JVM在执行Java程序的过程中会把它所管理的内存划分若干个不同的数据区域,如下图: 大致可以分为两类:线程私有区域和线程共享区域. 线程私有区域 程序计数器(Program Counter Regi ...
随机推荐
- 几组不错的X264自定义编码<转>
转帖地址:http://tieba.baidu.com/p/4201033507 一般直播时使用A设定即可.你尝试设置并找出你最满意的设定 A为最需最低CPU资源,E为最高. A8x8dct=1 aq ...
- javascript中defer的作用
javascript中defer的作用 <script src="../CGI-bin/delscript.js" defer></script>中的def ...
- HDFS设计理念
[HDFS设计理念] 1. 读取整个数据集的时间延迟比读取第一条记录的延迟更重要. 2. HDFS以高延迟为代价,要求低时间延迟数据访问的应用,不适合在HDFS上运行. 3. namenode决定了集 ...
- Django基础学习六之渲染
今天简单的介绍一下Django的template的渲染和Django的template的基本的语法 首先我们先启动一个django的shell,首先需要进入django的工程目录下启动django的s ...
- 清官谈mysql中utf8和utf8mb4区别
清官谈mysql中utf8和utf8mb4区别 发布时间:2015 年 10 月 4 日 发布者: OurMySQL 来源:JavaRanger - 专注JAVA高性能程序开发.JVM.Mysql优化 ...
- setitemdata 32位 or 64位
我用SetItemData 和GetItemData把数据库一条数据导入到CListctrl 32位下 程序都可以跑 GetItemData能得到自定义类数据 可以64位得不到?
- [SoapUI]怎样获取隐藏元素的文本内容Get text of hidden element
隐藏元素无法通过gettext()获取其文本内容,须用javascript来获取 String actualDataPointName = (String) ((JavascriptExecutor) ...
- 解决windows搭建jenkins执行selenium无法启动浏览器问题
因为jenkins是用windows installer 安装成windows的服务了,那么jenkins是一个后台服务,所以跑selium cases 的时候不显示浏览器 Step 1. Contr ...
- Page Object页面设计模式核心要点
Page Object,页面对象.一种设计模式,实施selenium的最佳实践,体现了web应用与页面显示之间的关系.为什么需要Page Object?测试代码维护的需要:减少代码的编码量,减少代 ...
- redhat6.7在线安装postgresql9
原文:http://wandejun1012.iteye.com/blog/2015777 1.安装postgresql9.0 yum 仓库 rpm -i http://yum.postgresql. ...