JVM(十一):内存分配

在前面的章节中,我们花了大量的篇幅去介绍 JVM 内的内存布局、对象在内存中的状态、垃圾回收的算法和具体实现等。今天让我们探讨一下对象是如何分配内存的。

堆内存划分

前面说过,从内存回收的角度来看,堆被分为以下几个部分:

开始创建的对象大多都会直接分配到新生代一块区域中,只有大对象和经过多次 GC 后依然存活的对象会放置在老年代中。

那么一个对象在被创建出来后,何时存在与哪个内存区域中呢,其具体的分配策略又是什么呢?下面就让我们一起来看一下几个具体的内存分配策略,了解一个对象在产生后该何去何从。

对象优先在Eden分配

首先,我们先复习一下 GC 的两种分类:

Minor GC,又叫新生代GC:发生在新生代的 GC,由于大多数 Java 对象都是朝生夕死的,因此发生这种 GC 十分的频繁,回收速度一般也会比较快。
Full/Major GC,又叫老年代GC:发生在老年代的 GC,一般会比 Minor GC 慢 10倍以上。

在大多数情况下,对象优先在 Eden 区进行分配。当 Eden 区空间不足时,将会发起一次 Minor GC。

大对象直接进入老年代

首先,我们来看一下什么是大对象,其一般是指需要大量连续内存空间的 Java 对象。最典型的就是很长的字符串和数组。对虚拟机来说大对象是很难处理的对象,因为虚拟机需要一块连续的大空间进行分配,不过更加难以处理的是朝生夕死的大对象,经常出现的大对象,导致频繁地触发 GC 来空出大量连续空间来安置它们,影响了性能。因此,这种情况也警醒开发人员在开发过程中要尽量避免这种问题。

长期存活对象进入老年代

因为 Java 的垃圾回收是采取的分代收集思想。因此新生代的对象也有一定的途径进入老年代,对应的就是存活时间,为了定位每个对象的存活时间,JVM 给每个对象定义了一个对象年龄计数器,当对象在 Survivor 区每熬过一次 Minor GC,对象的年龄就 +1,当对象的年龄满足一定的条件(默认为15),就将其晋升到老年代。

前面这种晋升老年代的条件显得比较的死板。因此在 JVM 中还有一种灵活的方式:如果在 Survivor 空间中相同年龄的所有对象综合大于 Survivor 空间的一半,那么年龄大于等于该阀值的对象就可以直接进入老年代,而无须等到满足要求的年龄。

空间分配担保

上面说过,在新生代经过 Minor GC 存活的对象,满足一定的条件会进入老年代 , 因此就需要保证老年代有充足的空间能够分配 。这种担保方式让 JVM 在进行 Full GC 的时候,可以进行大胆的操作 (因为 Full GC 十分的耗时,影响性能, 因此在 Minor GC 前需要进行一定的判断)。

上图就是空间分配担保的流程,此种方式可以避免 Full GC 过于频繁,影响性能。

总结

在本文中,我们详细讲述了对象内存分配的一些通用策略。了解这些策略可以让我们明白 JVM 分配对象的逻辑,写出更加高效健壮的代码。

文章在公众号「iceWang」第一手更新,有兴趣的朋友可以关注公众号,第一时间看到笔者分享的各项知识点,谢谢!笔芯!

本系列文章主要借鉴自《深入分析 JavaWeb 技术内幕》和《深入理解 Java 虚拟机-JVM 高级特性与最佳实践》。

最新文章

  1. SSH之免密码登录
  2. ajax 跨域访问
  3. 微信小程序上传文件
  4. Eclipse Che:下一代基于 Web 的 IDE
  5. paip.-Djava.library.path -Djava.ext.dirs= 的区别
  6. GetComponent
  7. php 面向对象要点汇总
  8. MyEclipse编码设置
  9. Net中的AOP
  10. Box2d FilterData
  11. Javasript 正则匹配任意字符
  12. 机器学习系统设计(Building Machine Learning Systems with Python)- Willi Richert Luis Pedro Coelho
  13. 2019-04-16 SpringMVC 学习笔记
  14. 关于JS 的cookie 操作 与 json 的数据结构 问题
  15. HDU ACM 1224 Free DIY Tour (SPFA)
  16. LIS LCS 最长上升子序列 最长公共子序列 ...
  17. SIM800C Couldn't pair with xxx because of an incorrect PIN or passkey
  18. Winform开发之DataGridView事件和属性
  19. LeetCode 289. Game of Life (C++)
  20. 盗COOKIE之方法总结

热门文章

  1. vmware + opensuse windows如何远程登录到suse上
  2. 重新认识 async/await 语法糖
  3. [PTA] 数据结构与算法题目集 6-4 链式表的按序号查找 & 6-5 链式表操作集 & 6-6 带头结点的链式表操作集
  4. 在安装Openstack的keystone认证服务时,出现The request you have made requires authentication. (HTTP 401) (Request-ID: req-f94bebba-f0c5-4a92-85问题的处理
  5. Linux 下载文件命令(wget)
  6. C#编程.函数.委托
  7. PHP--数据库访问(增、删、改、查)
  8. golang 时间转换的问题
  9. 2048 控制台版(C#)
  10. ioc和aop的区别