深入了解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 ...
随机推荐
- Visual Basic 函数速查
Calendar 常数 可在代码中的任何地方用下列常数代替实际值: 常数 值 描述 vbCalGreg 0 指出使用的是阳历. vbCalHijri 1 指出使用的是伊斯兰历法. Color 常数 可 ...
- 13 并发编程-(线程)-异步调用与回调机制&进程池线程池小练习
#提交任务的两种方式 #1.同步调用:提交完任务后,就在原地等待任务执行完毕,拿到结果,再执行下一行代码,导致程序是串行执行 一.提交任务的两种方式 1.同步调用:提交任务后,就在原地等待任务完毕,拿 ...
- Common Lisp
[Common Lisp] 1.操作符是什么? 2.quote. 3.单引号是quote的缩写. 4.car与cdr方法. 5.古怪的if语句. 6.and语句. 7.判断是真假. null 与 no ...
- x64位windows 2003 server中“Server 对象 错误 'ASP 0177 : 800700c1' Server.CreateObject 失败”问题
给朋友看一个老asp网站图片不能上传问题,试过网上各种办法都提示: Server 对象 错误 'ASP 0177 : 800700c1' Server.CreateObject 失败 最终问题出在x6 ...
- Java中的几种设计模式
如果从事JAVA相关的开发,都不可避免的要用到抽象和封装,这是JAVA的一个特点,同时也是每个开发者必须掌握的,JAVA是这样,Android更是如此.而设计模式就是告诉我们应该如何写出高效且更具应用 ...
- mybatis逆向工程的注意事项:mapper文件内容不是覆盖而是追加
XXXMapper.xml文件已经存在时,如果进行重新生成则mapper.xml文件内容不被覆盖而是进行内容追加,结果导致mybatis解析失败. 解决方法:删除原来已经生成的mapper xml文件 ...
- Python操作mysql之模块pymysql
pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同.但目前pymysql支持python3.x而后者不支持3.x版本. 本文环境 python3.6.1 Mysql ...
- ubuntu系统中解决github下载速度慢问题
如果你在使用github,出现访问和下载速度慢问题,可以通过修改host解决.记得不要踩坑哦!分四步: 第一步:查询速度快的IP地址 在http://tool.chinaz.com/dns中查询下面三 ...
- centos7 dubbokeeper安装
下载dubbokeeper源码 git clone https://github.com/dubboclub/dubbokeeper mysql 先执行install-mysql.sh 编译好 ...
- SpringMVC源码解读 - HandlerMapping
SpringMVC在请求到handler处理器的分发这步是通过HandlerMapping模块解决的.handlerMapping 还处理拦截器. 先看看HandlerMapping的继承树吧 可以大 ...