一、概要

前面的文章介绍了对象的创建过程,其中第三步 —— 分配内存,只是简单的介绍了分配的方式 —— 指针碰撞、空闲列表,其实内存在堆上分配还大有文章嘞。

对象的内存分配,往大方向上讲,就是在堆上分配,对象主要分配在新生代的 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系列四(内存分配策略).的更多相关文章

  1. JVM学习总结四——内存分配策略

    之前几篇我们介绍了jvm的内存模型以及垃圾回收机制,而本篇我们将介绍几个JVM中对象在分配内存是应该遵循的策略.毕竟,想要去优化程序,不仅要考虑垃圾回收的过程,还要从对象内存分配的角度减少gc的代价. ...

  2. JVM总结(二):JVM的内存分配策略

    这节我们总结一下JVM中的内存分配策略.目录如下: 内存分配策略 对象优先在新生代Eden分配 大对象直接进入老年代 长期存活的对象将进入老年代 动态对象年龄判定 空间分配担保 内存分配策略 Java ...

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

    垃圾收集器与内存分配策略 前言:本文基于<深入java虚拟机>再加上个人的理解以及其他相关资料,对内容进行整理浓缩总结.本文中的图来自网络,感谢图的作者.如果有不正确的地方,欢迎指出. 目 ...

  4. JVM性能优化系列-(2) 垃圾收集器与内存分配策略

    2. 垃圾收集器与内存分配策略 垃圾收集(Garbage Collection, GC)是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行在JVM上的语言,如 ...

  5. java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)

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

  6. 深入理解JVM(5)——垃圾收集和内存分配策略

    1.垃圾收集对象 垃圾收集主要是针对堆和方法区进行. 程序计数器.虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后也会消失,因此不需要对这三个区域进行垃圾回收. 哪 ...

  7. 深入了解java虚拟机(JVM) 第七章 内存分配策略

    理解了jvm内存分配策略不仅是程序性能调优的重要知识,还能够给养成自己一种良好的代码思路,一个程序的代码差异往往都是在这里体现出来的. 一.对象优先分配到Eden区域   一般来说,新创建的对象都会直 ...

  8. 【Java杂货铺】JVM#Java高墙之GC与内存分配策略

    Java与C++之间有一堵由内存动态分配和垃圾回收技术所围成的"高墙",墙外的人想进去,墙外的人想出来.--<深入理解Java虚拟机> 前言 上一章看了高墙的一半,接下 ...

  9. JVM学习笔记-第三章-垃圾收集器与内存分配策略

    JVM学习笔记-第三章-垃圾收集器与内存分配策略 tips:对于3.4之前的章节可见博客:https://blog.csdn.net/sanhewuyang/article/details/95380 ...

随机推荐

  1. Netflix 开源 Polynote:对标 Jupyter,一个笔记本运行多种语言

    谈到数据科学领域的开发工具,Jupyter 无疑是非常知名的一种.它具有灵活高效的特点,非常适合进行开发.调试.分享和教学.近日,Netflix(奈飞)居然也玩起了跨界,他们开源了一个名为 Polyn ...

  2. 扛把子组20191107-8 beta week 2/2 Scrum立会报告+燃尽图 07

    此作业的要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/9960 一.小组情况 队名:扛把子 组长:孙晓宇 组员:宋晓丽 梁梦瑶 韩 ...

  3. "PSP助手”微信小程序宣传视频链接及内容介绍

    此作业的要求参见[https://edu.cnblogs.com/campus/nenu/2019fall/homework/8677] 队名:扛把子组 组长:迟俊文 组员:刘信鹏 韩昊 宋晓丽 梁梦 ...

  4. Java方法之定义形式及可变参数

    目录 Java方法之定义形式及可变参数 方法调用 使用static修饰的方法 没有static修饰的方法 方法的定义格式 无参无返 无参有返 有参无返 有参有返 形参个数可变的方法 采用数组形参来定义 ...

  5. UINavigationController-自定义导航栏标题按钮.

    见视频0416 自定义导航栏标题按钮,在Bar Button Item中加入UIButton,设置UIButton的图片和标题,还可以自定义自定义UIButton实现特效按钮.

  6. LESSON 1-Introduction

    Keywords: Communication system, Channel model, Channel capacity by Shannon 1. Two fundamental archit ...

  7. Find命令、文件名后缀、Linux和Windows互传文件 使用介绍

    第2周第5次课(3月30日) 课程内容: 2.23/2.24/2.25 find命令2.26 文件名后缀 2.27 Linux和Windows互传文件 find命令 文件查找: 1.which(一般用 ...

  8. MyEclispe启动Tomcat7时出现错误The servlets named [LoginServlet] and [com.liu.control.LoginServlet] are both

    刚开始尝试写Servlet代码,第一天就碰到这个错误,在网上找了很多资料才找到解决办法,在此记录一下. org.apache.catalina.LifecycleException: Failed t ...

  9. 【JZOJ】3490. 旅游题解报告

    题目 思路 这道题看上去就像一个动态规划!但是还是要把矩阵压成一行. 然后按 \(A\)数组 将结构体从小到大排个序. 随后我们开始了动规标准步骤: 确定状态 很显然, \(f_i\) 表示游览完第\ ...

  10. linux中安装tensorflow

    liunxsudo apt-get install python-pip python-dev python2.X -> pippython3.X -> pip3 pip --versio ...