JVM系列四(内存分配策略).
一、概要
前面的文章介绍了对象的创建过程,其中第三步 —— 分配内存,只是简单的介绍了分配的方式 —— 指针碰撞、空闲列表,其实内存在堆上分配还大有文章嘞。
对象的内存分配,往大方向上讲,就是在堆上分配,对象主要分配在新生代的 Eden 区上,如果启动了本地线程分配缓冲,将按线程优先在 TLAB 上分配。少数情况下也可能直接分配在老年代中,分配的规则并不是百分之百固定的。其细节取决于当前使用的是哪一种垃圾收集器的组合,还有虚拟机中与内存相关的参数的设置。

下面介绍一些常见的内存分配策略。
二、对象优先在 Eden/TLAB 分配
虚拟机将新生代内存分为一块较大的 Eden 空间和两块较小的 Survivor 空间(默认比例是 8:1:1),大多数情况下,分配对象时,使用 Eden 和其中一块 Survivor 空间,当没有足够空间进行分配时,虚拟机将会进行一次 MinorGC。
如果虚拟机打开了 TLAB,那么对象优先在 TLAB 上分配。TLAB 全称是本地线程分配缓冲(Thread Local Allocation Buffer),它是每个线程在 Java 堆中预先分配的一小块内存。因为 TLAB是线程私有的,没有锁开销,因此性能较好,在 JDK7 之后默认开启。
三、大对象直接进入老年代
虚拟机提供了一个 -XX:PretenureSizeThreshold 参数,令大于这个设置值的对象直接在老年代分配,这样做的目的是避免在 Eden 区和及两个 Survivor 区之间发生大量的内存复制。注意!该参数只对 Serial 和 ParNew 收集器有效,Parallel Scavenge 并不认识该参数。
一般我们代码中常见的大对象是指那种很长的字符串以及数组,写程序的时候应当避免,经常出现大对象容易导致内存还有不少空间时就提前触发垃圾收集以获取足够的内存空间来“安置”它们。
四、长期存活的对象将进入老年代
还记得前面文章我们介绍对象创建的时候,说到对象头中有一个 “GC 分代年龄” 吗?那么这个是做啥用的呢?
如果对象在 Eden 出生并经过第一次 Minor GC 后仍然存活,并且能被 Survivor 容纳的话,将被移动到 Survivor 空间中,并且对象年龄设为1。对象在 Survivor 空间中每“熬过”一次 Minor GC,年龄就增加 1 岁,当它的年龄到达一定程度(最大为 15 岁),就将会被晋升到老年代。对象晋升老年代的年龄阈值,可以通过参数 -XX:MaxTenuringThreshold 设置。
对象是否能够晋升到老年代,也不全由 -XX:MaxTenuringThreshold 参数控制,如果 Survivor 空间中相同年龄的所有对象大小总和大于 Survivor 空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代。
五、空间分配担保
新生代在发生 Minor GC 之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象之和(或者历次晋升老年代对象的平均大小)。如果这个条件不成立,那么虚拟机将直接进行 Full GC 动作;如果这个条件成立,那么虚拟机就会进行一次 Minor GC 操作,但是这次 Minor GC 是有风险的,因为比较的值是平均值,可能出现极端的情况 —— 大量对象在 Minor GC 后还存活,这时就只好在失败后重新发起一次 Full GC。
JVM系列四(内存分配策略).的更多相关文章
- JVM学习总结四——内存分配策略
之前几篇我们介绍了jvm的内存模型以及垃圾回收机制,而本篇我们将介绍几个JVM中对象在分配内存是应该遵循的策略.毕竟,想要去优化程序,不仅要考虑垃圾回收的过程,还要从对象内存分配的角度减少gc的代价. ...
- JVM总结(二):JVM的内存分配策略
这节我们总结一下JVM中的内存分配策略.目录如下: 内存分配策略 对象优先在新生代Eden分配 大对象直接进入老年代 长期存活的对象将进入老年代 动态对象年龄判定 空间分配担保 内存分配策略 Java ...
- jvm系列 (二) ---垃圾收集器与内存分配策略
垃圾收集器与内存分配策略 前言:本文基于<深入java虚拟机>再加上个人的理解以及其他相关资料,对内容进行整理浓缩总结.本文中的图来自网络,感谢图的作者.如果有不正确的地方,欢迎指出. 目 ...
- JVM性能优化系列-(2) 垃圾收集器与内存分配策略
2. 垃圾收集器与内存分配策略 垃圾收集(Garbage Collection, GC)是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行在JVM上的语言,如 ...
- java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...
- 深入理解JVM(5)——垃圾收集和内存分配策略
1.垃圾收集对象 垃圾收集主要是针对堆和方法区进行. 程序计数器.虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后也会消失,因此不需要对这三个区域进行垃圾回收. 哪 ...
- 深入了解java虚拟机(JVM) 第七章 内存分配策略
理解了jvm内存分配策略不仅是程序性能调优的重要知识,还能够给养成自己一种良好的代码思路,一个程序的代码差异往往都是在这里体现出来的. 一.对象优先分配到Eden区域 一般来说,新创建的对象都会直 ...
- 【Java杂货铺】JVM#Java高墙之GC与内存分配策略
Java与C++之间有一堵由内存动态分配和垃圾回收技术所围成的"高墙",墙外的人想进去,墙外的人想出来.--<深入理解Java虚拟机> 前言 上一章看了高墙的一半,接下 ...
- JVM学习笔记-第三章-垃圾收集器与内存分配策略
JVM学习笔记-第三章-垃圾收集器与内存分配策略 tips:对于3.4之前的章节可见博客:https://blog.csdn.net/sanhewuyang/article/details/95380 ...
随机推荐
- K8s & Openshift案例学习
1. openshift排错技巧:https://mp.weixin.qq.com/s?__biz=MzAwMDc2NjQ4Nw==&mid=2663494178&idx=1& ...
- PHP安全之道学习笔记2:编码安全指南
编码安全指南 编程本身就应该是一门艺术,而安全编程更是一种在刀尖上舞蹈的艺术,不仅要小心脚下的锋利寒刃,更要小心来自网络黑客或攻击者的狂轰乱炸. - by code artist 1.hash比较的缺 ...
- MyBaits框架入门总结
MBaits简介 联系方式:18873247271(微信同步) 廖先生 qq:1727292697 MyBatis的前身叫iBatis,本是apache的一个开源项目, 2010年这个项目由apach ...
- 关于Java中2.0-1.1!=0.9的问题
关于Java中2.0-1.1!=0.9的问题 问题引出: 在<Java核心技术>中关于浮点数值计算部分提到,System.out.println(2.0-1.1)这条语句并不是想当然的0. ...
- pandas dataframe重复数据查看.判断.去重
本文详解如何使用pandas查看dataframe的重复数据,判断是否重复,以及如何去重 dataframe数据样本: import pandas as pd df = pd.DataFrame({' ...
- 在UEFI+GPT下使用rEFind实现Win10 + Kali2.0 双引导
转载自:在UEFI+GPT下使用rEFind实现Win10 + Kali2.0 双引导 https://www.linuxidc.com/Linux/2016-07/133717.htm
- Matlab查看本机IP地址---xdd
复制粘贴于http://www.matlabsky.com/thread-28597-1-1.html [s, r]=system('ipconfig') % r=regexp(r,'IP Addre ...
- 洛谷P1426-小鱼会有危险吗
原题链接: https://www.luogu.org/problem/P1426 题面简述: 有一次,小鱼要从A处沿直线往右边游,小鱼第一秒可以游7米,从第二秒开始每秒游的距离只有前一秒的98%98 ...
- linux防火墙的相关命令
一.iptables防火墙(需要安装防火墙sudo apt-get install firewalld命令查看插件)1.基本操作 # 查看防火墙状态 service iptables status # ...
- 预分配——fallocate的前世今生
最近比较懒,还是加班写点东西吧,不然过段时间又把这些整理的东西弄丢了. 写什么呢?写一些跟工作相关的吧!因为笔者从事多媒体录像相关的开发工作,因此常常涉及到优化写卡策略.提升写卡性能相关的方面的事情. ...