深入了解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 ...
随机推荐
- Maven - Deploy war in Tomcat 7 & 8
This article will explain on how to deploy a war fine in to Tomcat 7 through maven build. Note : I h ...
- zk分布式锁-排它锁简单实现-优化版
package Lock; import java.util.Collection;import java.util.Collections;import java.util.List;import ...
- confd test
vi /etc/confd/confd.toml backend = "consul"confdir = "/etc/confd"log-level = &qu ...
- centos7 搭建svn服务
linux(centos)下SVN服务器如何搭建?说到SVN服务器,想必大家都知道,可以是在LINUX下如何搭建SVN服务器呢?那么今天给大家分享一下linux(centos)搭建SVN服务器的思路! ...
- 19-python 自己建立词库并实现文章汉语词频统计
首先在网上下载一个汉语词典的txt文件, 汉语词典 1.用正则去掉词语的解释,即提取出所有汉语词语: import re def getHanYuCi(st): p = re.compile(r'[. ...
- 可跨平台C++开源图形图像框架:openFrameworks
博客参考:https://www.hahack.com/codes/openframeworks-intro/#%E4%BB%80%E4%B9%88%E6%98%AF-openframeworks 和 ...
- 多个docker 挂载VOLUME的心得
假如有一个mysql镜像 在Dockerfile中制定VOLUME /var/lib/mysql 那么当执行: docker run -d -e MYSQL_ROOT_PASSWORD=root -- ...
- HDU 2036 改革春风吹满地 (计算几何)
题意:你懂得. 析:没什么可说的,求面积用叉乘,尽量不要用海伦公式,因为计算量大,而且精度损失. 代码如下: #include <iostream> #include <cstdio ...
- PL/SQL Developer 窥探事务
一次登录代表一个连接 一个SQL Window 代表一个会话(session),有唯一的SID 事务(transaction) 由 insert .update 或者 delete 开启 由 comm ...
- B-spline Curves 学习之B样条基函数计算实例(3)
B-spline Basis Functions: Computation Examples 本博客转自前人的博客的翻译版本,前几章节是原来博主的翻译内容,但是后续章节博主不在提供翻译,后续章节我在完 ...