`
Turandot
  • 浏览: 52770 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

Java 内存分配策略

阅读更多

Java 内存分配策略

 

   对象的内存分配,往大方向上讲,就是在堆上分配(但是可能经过JIT编译器后被扯散为标量类型并间接地在栈上分配),对象主要分配在新生代的Eden区上,如果启动了本地线程分配缓冲,将按线程优先在线程私有的分配缓存区(TLAB-Thread Local Allocation Buffer)。少数情况下也可能直接分配在老年代中,分配的规则并不是百分百之固定的,其细节取决于当前使用的是哪一种垃圾收集器组合,还有虚拟机中与内存相关的参数的设置。

 

  1. 对象优先在Eden分配

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

        我们设置堆的大小为20MB,新生代10MB,新生代Eden区与一个Survivor区的空间比例为8:1,老年代为10MB。尝试先分配3个MB大小的对象X1,X2,X3,再分配一个4MB大小的对象X4。当分配对象X4时,会发生一次Minor GC,当然X1,X2,X3都是存活的。这次GC发生的原因是给X4分配内存的时候,发现Eden已经被占用了6MB,剩余空间已不足以分配X4所需的内存,因此发生GC。GC期间虚拟机又发现已有的3个对象X1,X2,X3全部无法进入Survivor空间,所有只好通过分配担保机制提前转移到老年代去。

 

        新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多都具有朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。

        老年代GC(Major GC/Full GC ):指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC。Major GC的速度一般会Minor GC慢10倍以上。

 

 

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

 

        所谓大对象就是指,需要大量连续对象内存空间的Java对象,最典型的大对象就是那种很长的字符串及数组。虚拟机提供一个 -XX:PretenureSizeThreshold参数,令大于这个设置值的对象直接在老年代中分配。这样做的目的是避免在Eden区及两个Survivor区之间发生在大量的内存拷贝(新生代采用复制算法收集内存)。

 

   3.  长期存活的对象将进入老年代

 

         虚拟机采用分代收集的思想来管理内存,那内存回收时就必须能识别那些对象应当放在新生代,那些对象应放在老年代中。为了做到这一点,虚拟机给每个对象定义了一个对象年龄(Age)计数器。如果对象在Eden出生并经过第一次Minor GC都仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并将年龄设为1.对象在Survivor区中每熬过一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认为15岁)时,就会被晋升到老年代中。对象晋升老年代的年龄阀值,可以通过参数-XX:MaxTenuringThreshold来设置。

 

   4.  动态对象年龄判定

 

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

 

   5.  空间分配担保

        

         在发生Minor GC时,虚拟机会检测之前每次晋升到老年代的平均大小是否大于老年代剩余空间大小,如果大于,则改为直接进行一次Full GC 。如果小于,则查看HandlePromotionFailure设置是否允许担保失败;如果允许只会进行Minor GC;如果不允许,则改为进行一次Full GC。

        老年代要进行这样的担保,前提是老年代本身还有容纳这些对象的剩余空间,一共有多少对象会活下来,在实际完成回收之前是无法确定的,所以只好取之前每一次晋升到老年代对象容量的平均值作为经验值,与老年代的剩余空间进行比较,决定是否进行Full GC 来让老年代腾出更多的空间。

         取平均值进行比较其实仍然是一种动态的概率手段,也即是说如果某次Minor GC 存活后的对象剧增,远远高于平均值的话,依然到导致担保失败。如果出现了担保失败,那就只好在失败后中心发起一次Full GC 。大部分情况下都还是将HandlePromotionFailure开关打开,避免Full GC过于频繁。

0
0
分享到:
评论

相关推荐

    Java内存分配及垃圾回收文章汇总

    本篇将深入探讨Java内存分配策略以及垃圾回收机制,以帮助你更好地理解和解决相关问题。 首先,我们来看JVM的内存结构。在JDK5.0中,JVM的堆内存被分为新生代(Young Generation)、老年代(Tenured Generation)和...

    Java中堆内存与栈内存分配浅析

    Java内存分配策略包括静态存储分配、栈式存储分配和堆式存储分配。静态存储分配在编译时就确定了变量的内存需求,栈式分配在运行时按需分配,而堆式分配则处理编译时和运行时都无法确定存储需求的数据结构,如可变...

    JAVA中的内存分配策略

    ### JAVA中的内存分配策略 #### 一、内存分配的基本概念 在探讨JAVA中的内存分配策略之前,我们需要了解一些基本的概念。 - **静态存储分配**:指的是在编译时就能确定每个数据目标在运行时刻的存储空间需求,...

    java内存分配情况

    Java内存分配主要涉及五个区域:寄存器、栈、堆、静态域和常量池。在Java编程中,理解这些内存区域的分配规则对于优化代码性能和避免内存泄漏至关重要。 1. **寄存器**:这是最快捷的存储区域,但不在Java程序员的...

    JAVA内存管理模式研究.pdf

    本文将详细介绍 Java 的内存管理模式,包括内存区域、内存分配策略、垃圾回收机制等。 一、Java 内存区域 Java 程序在运行时,JVM 会提供以下几个内存区域: * 方法区:存放静态变量和方法信息。 * 栈区:存放...

    【Java正来-Java虚拟机专题】-Java垃圾收集器与内存分配策略

    主要整理内容为:分析了垃圾收集的算法和JDK1.7中提供的7款垃圾收集器的特点以及运作原理。以及内存分配策略

    java内存分配演示程序

    9. **Java虚拟机参数调整**:开发者可以通过JVM参数来调整内存分配策略,例如-Xms和-Xmx设置堆内存的初始大小和最大大小,-XX:NewRatio设置新生代和老年代的比例等。 10. **JVM内存诊断工具**:JVisualVM、jmap、...

    java 内存分配 适应法

    内存分配策略对于程序的性能和资源利用率具有深远影响。本篇文章将深入探讨Java内存分配中的“最先适应法”、“最佳适应法”和“最坏适应法”,这些都是内存管理中的经典算法,适用于不同的场景和需求。 首先,我们...

    深入Java核心_Java内存分配原理精讲

    Java内存分配原理是Java编程中的重要一环,它关乎到程序的性能、稳定性和资源管理。深入理解这一主题,能够帮助开发者编写出更高效、更稳定的代码。在Java中,内存分为堆内存、栈内存、方法区(在Java 8之后被元空间...

    java实现的内存分配

    Java内存分配的核心机制是垃圾收集(Garbage Collection, GC),它负责自动回收不再使用的内存。Java提供了几种不同的垃圾收集器,如Serial、Parallel、Concurrent Mark Sweep (CMS) 和G1等,它们各有优缺点,适用于...

    java内存对象分配过程研究

    这些数据的存储顺序会受到虚拟机分配策略参数(如/CompactFields)和字段在Java源码中的顺序的影响。 3. **对齐填充(Padding)**:由于虚拟机要求对象起始地址必须是8字节的整数倍,填充是为了让对象大小符合这一要求而...

    深入Java核心 Java内存分配原理精讲

    深入探讨Java核心:Java内存分配原理精讲 Java内存分配机制是Java编程语言的重要组成部分,它不仅直接影响着程序的性能,也是理解Java垃圾回收、内存泄漏等问题的关键。本文将聚焦于Java内存分配的核心概念,包括栈...

    java内存分配 内存泄漏

    理解Java内存分配和JVM工作原理对于开发高效、健壮的Java应用至关重要。开发者应避免内存泄漏,合理使用内存,充分利用JVM的垃圾收集机制,同时理解JIT编译的优化策略,以提高程序的运行性能。在开发过程中,使用...

    JAVA 垃圾收集器与内存分配策略.rar

    在Java编程语言中,垃圾收集器(Garbage Collector, GC)和内存分配策略是至关重要的概念,它们确保了程序的高效运行和内存的有效管理。Java的自动内存管理系统使得程序员无需手动管理内存,而是由JVM(Java虚拟机)...

    Java内存分配原理

    Java内存分配原理是Java编程中不可或缺的基础概念,它关乎程序的...总的来说,Java内存分配涉及程序的性能、资源管理以及垃圾回收策略。理解这些原理对于开发高质量的Java应用至关重要,也是Java程序员必备的基础知识。

    java程序中的内存分配问题

    Java程序在运行时的内存分配是一个关键的概念,它关乎...理解并掌握这些Java内存分配的知识点,对于编写高效、稳定的Java程序至关重要。通过实践和深入学习,开发者可以更好地控制程序的内存使用,减少错误,提升性能。

    经典之谈——Java内存分配

    Java内存分配的策略直接影响到程序的性能。在堆内存中,对象的创建和垃圾收集是重点关注的部分。垃圾收集器主要负责识别不再使用的对象并释放其占用的内存,常见的垃圾收集算法有标记-清除、复制、标记-整理和分代...

Global site tag (gtag.js) - Google Analytics