一、概要

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

对象的内存分配,往大方向上讲,就是在堆上分配,对象主要分配在新生代的 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. Alibaba Nacos 学习(五):K8S Nacos搭建,使用nfs

    Alibaba Nacos 学习(一):Nacos介绍与安装 Alibaba Nacos 学习(二):Spring Cloud Nacos Config Alibaba Nacos 学习(三):Spr ...

  2. 2019-10-12,html+php+mysql简单留言板,作业

    php+mysql简易留言板,实现注册,登录,注销,查看留言,删除留言 1,index.html登录页面 代码: <!doctype html> <html> <head ...

  3. web网站常用功能测试点总结

    目录 一.输入框 二.搜索功能 三.添加.修改功能 四.删除功能 五.注册.登录模块 六.上传图片测试 七.查询结果列表 八.返回键检查 九.回车键检查 十.刷新键检查 十一.直接URL链接检查 十二 ...

  4. jquery怎么添加多个类名

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Java基础面试题及答案(二)

    容器 18. java 容器都有哪些? 常用容器的图录: 19. Collection 和 Collections 有什么区别? java.util.Collection 是一个集合接口(集合类的一个 ...

  6. mr的partition分区

    1.Partitioner 组件通过让 Map 对 Key 进行分区,从而将不同分区的 Key 交由不同的 Reduce 处理.Partition属于map端 2.分区的总数与任务的reduce任务数 ...

  7. jquery树形结构

    <div class="tree_content"> <div class="tree_node"> <div class=&qu ...

  8. docker-primary

    docker-ce  docker网址 https://docs.docker.com/docsarchive/ Docker的安装和启动 官方安装文档链接:https://docs.docker.c ...

  9. css实现input表单验证

    有没有办法只通过css来确定input标签是否有输入? 我有这个想法是因为我想完成一个自动补全的input部件,最基本的功能是: 如果input没有内容,这隐藏下拉框 反之,显示下拉框 我找到了一个也 ...

  10. 使用Python开发小说下载器,不再为下载小说而发愁 #华为云·寻找黑马程序员#

    需求分析 免费的小说网比较多,我看的比较多的是笔趣阁.这个网站基本收费的章节刚更新,它就能同步更新,简直不要太叼.既然要批量下载小说,肯定要分析这个网站了- 在搜索栏输入地址后,发送post请求获取数 ...