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. spark 源码分析之十五 -- Spark内存管理剖析

    本篇文章主要剖析Spark的内存管理体系. 在上篇文章 spark 源码分析之十四 -- broadcast 是如何实现的?中对存储相关的内容没有做过多的剖析,下面计划先剖析Spark的内存机制,进而 ...

  2. 【DFS练习】-翻棋子-C++

    Description 有一个4*4的棋盘,放有16枚棋子. 每个棋子都是一面黑一面白,一开始有的黑面朝上,有的白面朝上. 下面是一个例子,这个例子用文字描述为: bwbw wwww bbwb bww ...

  3. exe崩溃用windbgattach后有宝贵现场,可看程序退出线程等,千万不要清屏

    exe崩溃用windbgattach后有宝贵现场,可看程序退出线程等,千万不要清屏

  4. python面向过程编程小程序 -ATM(里面用了终端打印)

    06.09自我总结 1.文件摆放 ├── xxxx │ ├── run.py │ └── fil_mode.py │ └── data_time.py │ └── loading.py │ └── d ...

  5. markdown插入表格语法

    markdown插入表格语法 举例 如表格标题为,姓名,班级,成绩 标题内的内容为,yang,a班,100 我们要在markdow文件中插入表格 如 姓名|班级|成绩 -|-|- yang|a班|10 ...

  6. RecyclerView下拉加载集合越界问题

    问题描述 在做毕业设计app中遇到这样一个问题,使用RecyclerView进行下拉加载数据的时候,比如我每次让它加载5条数据,当服务器端数据总数刚好是5的倍数的时候,不会出现下拉加载数据集合越界的问 ...

  7. [leetcode] 905. Sort Array By Parity [easy]

    原题链接 很水的一道题,就是数组内部交换. 水题就想着减少复杂度嘛,于是学到一种交换写法. class Solution { public: vector<int> sortArrayBy ...

  8. 关于Object.defineProperty 的基础知识

    Object.defineProperty 这个方法大家耳熟能详,可以对 对象的属性进行添加或修改的操作.即可以进行  数据劫持 .vue就是通过这个方法来劫持数据的. 平时我们创建对象的时候,一般通 ...

  9. 【SVN】SVN使用教程总结

    SVN使用教程总结 SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本,这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版本. Subve ...

  10. DH、RSA与ElGamal非对称加密算法实现及应用

    1.对称加密与非对称加密概述 关于对称加密与非对称加密的概念这里不再多说,感兴趣可以看下我之前的几篇文章,下面说一说两者的主要区别. 对称加密算法数据安全,密钥管理复杂,密钥传递过程复杂,存在密钥泄露 ...