Java虚拟机-内存分配策略

简介: Java虚拟机-内存分配策略

 image.gif编辑

 

Java技术体系中的自动内存管理可以归结为自动化的解决了两个问题:给对象分配内存和回收分配给对象的内存。前面讲的是内存回收,这章讲如何为对象分配内存。

一、内存分配策略概述

对象的内存分分配主要是指堆上分配(也可栈上分配),对象主要分配在新生代Eden区,如果启动了本地线程分配缓冲,则按照线程优先在TLAB上分配。少数情况下也会直接分配在老年代,分配的规则不固定,取决于垃圾回收器组合以及JVM中与内存相关参数的设置。

我们以Serial/Serial Old收集器为例进行介绍。

二、内存分配策略

1.对象优先在Eden区分配

大多数情况下,对象在新生代的Eden区中分配,当Eden区没有足够空间进行分配时,虚拟机将会发起一次Minor GC。

2.大对象直接进入老年代

大对象是指需要大量连续内存空间的Java对象,典型大对象有长字符串和数组,大对象对虚拟机的内存分配来说是一个坏消息,写程序时还要避免创建一些朝生夕死的短命大对象,经常出现大对象容易导致内存还有不少空间时就提前触发垃圾收集以获取足够的连续空间来安置他们。

虚拟机提供-XX:PretenureSizeThreshold参数,令大于这个设置值的对象直接在老年代分配,这样避免再Eden及两个Survivor区间发生大量的内存复制,这个参数只对Serial和ParNew两款收集器有效,如果遇到必须使用此参数的场合,可以考虑ParNew加CMS的组合。

大对象直接在老年代进行分配的目的是避免在Eden区和两个Survivor区之间发生大量的内存复制。

3.根据对象年龄判定进入老年代

虚拟机给每个对象定义了一个对象年龄计数器,如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并且对象年龄设为1,对象在Survivor区中每熬过一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认为15岁),就会被晋升到老年代中,可以通过-XX:MaxTenuringThreshold参数来设置年龄阈值。

4.动态对象年龄判断

为了能更好的适应不同程序的内存情况,虚拟机不是永远的要求对象的年龄必须达到阈值才能晋升老年代;如果在Survivor区中的相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或者等于该年龄的对象就可以直接进入老年代,无须等到-XX:MaxTenuringThreshold 中要求的年龄。

5.空间分配担保

关于分配担保机制JDK6前后有差别的。  

JDK6之前

当发生Minor GC时,JVM会首先检查老年代最大的可用连续空间是否大于新生代所有对象的总和,如果大于,那么这次Minor GC是安全的,如果不大于的话,JVM就需要判断HandlePromotionFailure是否允许空间分配担保。

如果允许担保失败,那么JVM会继续检查老年代最大的可用连续空间是否大于历次晋升到老年代的对象的平均大小:

    • 如果大于,则正常进行一次YGC,尽管有风险(因为判断的是平均大小,有可能这次的晋升对象比平均值大很多);
    • 如果小于,或者HandlePromotionFailure设置不允许空间分配担保,这时要进行一次FGC。

    对以上的步骤归纳一下,先看老年代的可用空间能否容下新生代的所有对象,不能的话看是否开启了分配担保机制,允许就先执行Minor GC,否则直接进行Full GC。大部分情况下还是会将HandlePromotionFailure开启分配担保,避免频繁Full GC。

    JDK6后

    HandlePromotionFailure不再影响到虚拟机的空间分配担保策略,变为只要老年代的连续空间大于新生代对象总大小或历次晋升的平均大小就会进行Minor GC,否则将进行Full GC。

    三、概念充电

    Minor GC和Major GC/Full GC:

      • 新生代GC(Minor GC:缩写YGC,指发生在新生代的垃圾回收动作,因为Java对象大多都具备朝生夕灭的特性,所以Monir GC非常频繁,一般回收速度也比较快。
      • 老年代GC(Major GC/Full GC):指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC(但并非绝对的,在Parallel Scavenge)收集器的收集策略里就有直接进行Major GC的策略选择过程。Major GC的速度一般比Major GC慢10倍以上。

      参考资料:

        1. JVM系列(四)内存分配策略_西海幼鸟的博客-CSDN博客
        2. JVM学习之—垃圾回收与内存分配策略 - 简书
        3. JVM理论:(二/1)内存分配策略 - 湮天霸神666 - 博客园
        相关文章
        |
        16天前
        |
        监控 算法 Java
        Java中的内存管理:理解Garbage Collection机制
        本文将深入探讨Java编程语言中的内存管理,特别是垃圾回收(Garbage Collection, GC)机制。我们将从基础概念开始,逐步解析垃圾回收的工作原理、不同类型的垃圾回收器以及它们在实际项目中的应用。通过实际案例,读者将能更好地理解Java应用的性能调优技巧及最佳实践。
        58 0
        |
        10天前
        |
        存储 缓存 Java
        java线程内存模型底层实现原理
        java线程内存模型底层实现原理
        java线程内存模型底层实现原理
        |
        6天前
        |
        存储 算法 Java
        深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
        本文介绍了 JVM 的内存区域划分、类加载过程及垃圾回收机制。内存区域包括程序计数器、堆、栈和元数据区,每个区域存储不同类型的数据。类加载过程涉及加载、验证、准备、解析和初始化五个步骤。垃圾回收机制主要在堆内存进行,通过可达性分析识别垃圾对象,并采用标记-清除、复制和标记-整理等算法进行回收。此外,还介绍了 CMS 和 G1 等垃圾回收器的特点。
        18 0
        深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
        |
        12天前
        |
        缓存 监控 NoSQL
        阿里面试让聊一聊Redis 的内存淘汰(驱逐)策略
        大家好,我是 V 哥。粉丝小 A 面试阿里时被问到 Redis 的内存淘汰策略问题,特此整理了一份详细笔记供参考。Redis 的内存淘汰策略决定了在内存达到上限时如何移除数据。希望这份笔记对你有所帮助!欢迎关注“威哥爱编程”,一起学习与成长。
        |
        12天前
        |
        Java 编译器
        深入理解Java内存模型:从基础到高级
        本文旨在通过通俗易懂的方式,引导读者深入理解Java内存模型(JMM)的核心概念和工作原理。我们将从简单的基础知识入手,逐步探讨重排序、顺序一致性问题以及volatile关键字的实现机制等高级主题。希望通过这篇文章,你能够对Java内存模型有一个清晰、全面的认识,并在实际编程中有效地避免并发问题。
        |
        10天前
        |
        存储 算法 Java
        深入理解Java内存管理
        本文将通过通俗易懂的语言,详细解析Java的内存管理机制。从JVM的内存结构入手,探讨堆、栈、方法区等区域的具体作用和原理。进一步分析垃圾回收机制及其调优方法,最后讨论内存泄漏的常见场景及防范措施。希望通过这篇文章,帮助读者更好地理解和优化Java应用的内存使用。
        |
        14天前
        |
        监控 算法 Java
        Java中的内存管理与垃圾回收机制
        本文将深入探讨Java编程语言中的内存管理方式,特别是垃圾回收(Garbage Collection, GC)机制。我们将了解Java虚拟机(JVM)如何自动管理内存,包括对象创建、内存分配以及不使用对象的回收过程。同时,我们还将讨论不同的垃圾回收算法及其在不同场景下的应用。
        |
        13天前
        |
        监控 算法 Java
        深入理解Java中的垃圾回收机制在Java编程中,垃圾回收(Garbage Collection, GC)是一个核心概念,它自动管理内存,帮助开发者避免内存泄漏和溢出问题。本文将探讨Java中的垃圾回收机制,包括其基本原理、不同类型的垃圾收集器以及如何调优垃圾回收性能。通过深入浅出的方式,让读者对Java的垃圾回收有一个全面的认识。
        本文详细介绍了Java中的垃圾回收机制,从基本原理到不同类型垃圾收集器的工作原理,再到实际调优策略。通过通俗易懂的语言和条理清晰的解释,帮助读者更好地理解和应用Java的垃圾回收技术,从而编写出更高效、稳定的Java应用程序。
        |
        5天前
        |
        存储 缓存 NoSQL
        Redis 过期删除策略与内存淘汰策略的区别及常用命令解析
        Redis 过期删除策略与内存淘汰策略的区别及常用命令解析
        13 0
        |
        4月前
        |
        监控 Java 调度
        探秘Java虚拟机(JVM)性能调优:技术要点与实战策略
        【6月更文挑战第30天】**探索JVM性能调优:**关注堆内存配置(Xms, Xmx, XX:NewRatio, XX:SurvivorRatio),选择适合的垃圾收集器(如Parallel, CMS, G1),利用jstat, jmap等工具诊断,解决Full GC问题,实战中结合MAT分析内存泄露。调优是平衡内存占用、延迟和吞吐量的艺术,借助VisualVM等工具提升系统在高负载下的稳定性与效率。
        86 1
        下一篇
        无影云桌面