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 高级特性与最佳实践》。

JVM(十一):内存分配的更多相关文章

  1. JVM初探- 内存分配、GC原理与垃圾收集器

    JVM初探- 内存分配.GC原理与垃圾收集器 标签 : JVM JVM内存的分配与回收大致可分为如下4个步骤: 何时分配 -> 怎样分配 -> 何时回收 -> 怎样回收. 除了在概念 ...

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

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

  3. JVM的内存分配垃圾回收策略

    之前看过<深入了解Java虚拟机>感觉容易忘,今天写一篇博客加深一下印象. JVM的内存分配和垃圾回收(GC)主要发生在Java堆中.而Java堆根据对象的存活时间可以分为新生代和老年代, ...

  4. 一夜搞懂 | JVM GC&内存分配

    前言 本文已经收录到我的Github个人博客,欢迎大佬们光临寒舍: 我的GIthub博客 学习导图 一.为什么要学习GC&内存分配? 时代发展到现在,如今的内存动态分配与内存回收技术已经相当成 ...

  5. jvm的内存分配总结

    最近看了周志明版本的<深入理解Java虚拟机>第一版和第二版,写的很好,收获很多,此处总结一下.   jvm中内存划分:   如上图,一共分为五块,其中: 线程共享区域为: 1.java堆 ...

  6. JVM的内存分配与垃圾回收策略

    自动内存管理机制主要解决了两个问题:给对象分配内存以及回收分配给对象的内存. >>垃圾回收的区域 前面的笔记中整理过虚拟机运行数据区,再看一下这个区域: 注意在这个Runtime Data ...

  7. 浅谈JVM与内存分配

    一.程序内存分配 初始内存分配 当一个程序准备运行时,它首先向java虚拟机要内存,但是java虚拟机本身没有权限,它只能向操作系统申请内存,此时java虚拟机会拥有一个初始内存, 此处额外说明一下e ...

  8. jvm对象内存分配

    一.jvm简单结构图 1.jvm内存对象分配整体流程: 1.类加载子系统和方法区 类加载子系统负责从文件系统或者网络中加载Class信息,加载的类信息存放于一块称为方法区的内存空间.除了类的信息外, ...

  9. 【面试必备】小伙伴栽在了JVM的内存分配策略。。。

    周末有小伙伴留言说上周面试时被问到内存分配策略的问题,但回答的不够理想,小伙伴说之前公号里看过这一块的文章的,当时看时很清楚,也知道各个策略是干嘛的,但面试时脑子里清楚,心里很明白,但嘴里就是说不清楚 ...

  10. 认识JVM的内存分配

    当我们在JVM中运行一段程序代码,JVM初始运行的时候都会分配好Method Area(方法区)和Heap(堆),而JVM每遇到一个线程,就为其分配一个Program Counter Register ...

随机推荐

  1. Java volatile关键字小结

    public class Test { public static void main(String[] args){ } } /* 12.3 Java内存模型 Java内存模型定义了线程与主内存之间 ...

  2. dbo是默认用户也是架构

    dbo是默认用户也是架构 dbo作为架构是为了更好的与2000兼容, 在2000中DataBaseName.dbo.TableName解释为:数据库名.用户名.表名, 在2005中DataBaseNa ...

  3. Eclipse安装STS插件

    由于Spring的配置文件较多,基于Eclipse配置也比较复杂.为了提高开发的效率,建议使用STS开发工具开发,或者在Eclipse安装一个STS插件. 在开发者配置bean的class时候能够根据 ...

  4. Dock学习(一):容器介绍

    一.什么是容器 1.容器是一种轻量级.可移植.自包含的软件打包技术,使应用程序可以在几乎任何地方以相同的方式运行.开发人员在自己的笔记本上创建并测试好的容器,无需任何修改就能够在生产系统的虚拟机.或物 ...

  5. 马蜂窝 IM 系统架构的演化和升级

    今天,越来越多的用户被马蜂窝持续积累的笔记.攻略.嗡嗡等优质的分享内容所吸引,在这里激发了去旅行的热情,同时也拉动了马蜂窝交易的增长.在帮助用户做出旅行决策.完成交易的过程中,IM 系统起到了重要的作 ...

  6. 个人永久性免费-Excel催化剂功能第37波-把Sqlserver的强大分析函数拿到Excel中用

    本人一直钟情于使用Sqlserver数据库的一大原因是其提供了非常好用.高效的数据分析函数(窗口函数),可以在做数据清洗和数据分析场合等多个场景使用.只需简单的一个函数即可做出常规SQL语句很难以实现 ...

  7. Excel催化剂开源第14波-VSTO开发之单元格区域转DataTable

    在Excel开发过程中,大部分时候是和Range单元格区域打交道,在VBA开发中,大家都知道的一点是,不能动不动就去遍历所有单元格,那性能是非常糟糕的,很多时候,是需要把整个单元格区域装入数组中再作处 ...

  8. [leetcode] 67. Add Binary (easy)

    原题链接 思路: 用一个数保存进制,从后往前不断pop出两个数字和进制数相加,放入返回值中. var addBinary = function(a, b) { var arrA = a.split(' ...

  9. python面向对象-封装-property-接口-抽象-鸭子类型-03

    封装 什么是封装: # 将复杂的丑陋的隐私的细节隐藏到内部,对外提供简单的使用接口 或 # 对外隐藏内部实现细节,并提供访问的接口 为什么需要封装 1.为了保证关键数据的安全性 2.对外部隐藏内部的实 ...

  10. Java多线程笔记总结

    1.线程的三种创建方式 对比三种方式: 通过继承Thread类实现 通过实现Runnable接口 实现Callable接口 第1种方式无法继承其他类,第2,3种可以继承其他类: 第2,3种方式多线程可 ...