Java技术体系中所提倡的自动内存管理策略最终可以归结为自动化地解决了两个问题:给对象分配内存以及回收分配给对象的内存;

几条普遍的分配规则:
1、对象优先在Eden区分配
年轻代分为三个区:1个Eden区+2个Survivor区。
大部分对象在Eden区中生成(大对象可以直接被创建在年老代),还存活的对象将被复制到一个Survivor区,当这个Survivor区满时,此区的存活对象将被复制到剩下的一个Survivor区中,当这个Survivor区也满了的时候,从第一个Survivor复制过来的并且此时还存活的对象,将被复制到年老区。
需要注意的是,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden区复制过来的对象和从前一个Survivor区复制过来的对象,而复制到年老区的就只有从第一个Survivor区过去的对象。并且Survivor区总有一个是空的。
Minor GC(Young GC):对象被创建时,内存的分配首先发生在年轻代,大部分的对象在创建后很快就不再使用,因此很快变得不可达,于是被年轻代的GC机制清理掉,这个GC机制被称为Minor GC或Young GC。
注意Minor GC并不代表年轻代内存不足,它事实上只表示在Eden区上的GC。
由于绝大部分对象都是短命的,甚至存活不到Survivor区中,所以Eden与Survivor的比例较大,HotSpot默认为8:1.

在Eden区,HotSpot虚拟机使用了两种技术来加快内存分配。分别是bump-the-pointer和TLAB(Thread- Local Allocation Buffers),这两种技术的做法分别是:由于Eden区是连续的,因此bump-the-pointer技术的核心就是跟踪最后创建的一个对象,在对象创建时,只需要检查最后一个对象后面是否有足够的内存即可,从而大大加快内存分配速度;而对于TLAB技术是对于多线程而言的,将Eden区分为若干段,每个线程使用独立的一段,避免相互影响。TLAB结合bump-the-pointer技术,将保证每个线程都使用Eden区的一段,并快速的分配内存;

2、大对象直接分配在老年代
所谓的大对象是指的需要大量连续内存空间的Java对象。比如:那种很长的字符串以及数组。
经常出现大对象容易导致内存还有不少空间时就提前触发垃圾收集以获取足够的连续空间来“安置”它们;
年老代存放从年轻代存活的对象。一般来说年老代存放的都是生命周期较长的对象。
年老代的空间一般比年轻代大,能存放更多的对象,在年老代上发生的GC次数也比年轻代少。
当年老代内存不足时,将执行Major GC,也叫Full GC;
可能存在年老代对象引用新生代对象的情况,如果需要执行Young GC,则可能需要查询整个老年代以确定是否可以清理回收,这显然是低效的。解决的方法是,年老代中维护一个512 byte的块——”card table“,所有老年代对象引用新生代对象的记录都记录在这里。Young GC时,只要查这里即可,不用再去查全部老年代,因此性能大大提高。
一般,老年代用的算法是标记-整理算法,即:标记出仍然存活的对象(存在引用的),将所有存活的对象向一端移动,以保证内存的连续;

在发生Minor GC时,虚拟机会检查每次晋升进入老年代的大小是否大于老年代的剩余空间大小,如果大于,则直接触发一次Full GC,否则,就查看是否设置了-XX:+HandlePromotionFailure(允许担保失败),如果允许,则只会进行MinorGC,此时可以容忍内存分配失败;如果不允许,则仍然进行Full GC(这代表着如果设置-XX:+Handle PromotionFailure,则触发MinorGC就会同时触发Full GC,哪怕老年代还有很多内存,所以,最好不要这样做)。
使用-XX:PretenureSizeThreshold参数,令大于这个设置值的对象直接在老年代分配;这样的目的主要是为了避免在Eden区以及2个Survivor区之间发生大量的内存复制;
-XX:PretenureSizeThreshold参数只对Serial 和ParNew 收集器有效,Parallel Sacvenge收集器不认识此参数。
-XX:PretenureSizeThreshold参数的值不能像-Xms一样直接写3M要写成3145728;

3、长时间存活的对象分配在老年代
虚拟机采用了分代收集的思想来管理内存,那么内存回收时就必须能识别哪些对象在新生代,哪些对象应在老年代,所以,虚拟机给每个对象定义了一个对象年龄计数器;
如果对象在Eden区出生并经历一次Minor GC后仍然存活,并且能被Survivor区所容纳,那么对象年龄计数器值为1;
对象在Survivor区中每熬过一次Minor GC,年龄就会增加1;
默认年龄是15,可以通过设置-XX:MaxTenuringThreshold来设置。

4、动态对象年龄判定
为了能更好的适应不同程序的内存状况,虚拟机并不是永远都是要求对象的年龄达到了MaxTenuringThreshold才能晋升老年代;
如果在Survivor空间内相同年龄所有对象大小总和大于 Survivor空间的一半,年龄等于或大于该年龄的对象可以直接进入老年代,而无需达到MaxTenuringThreshold设定的年龄;

5、空间分配担保
在发生Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象的总和。如果条件成立,那么Minor GC可以确保是安全的;
如果不成立,那么虚拟机会查看HandlerPromotionFailure设置值是否允许担保失败。
如果允许,会检查老年代最大可 用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,则尝试进行一次Minor GC;如果小于,则会进行一次Full GC

转载于:https://www.cnblogs.com/time-info/p/4514190.html

Java虚拟机-内存分配策略相关推荐

  1. Java虚拟机内存分配策略

    1.JVM内存分配分区 Java的内存简单分为堆内存和非堆内存 其中堆内存又可以分为新生代和老年代 新生代分为1个Eden区和2个Survivor区,如下图: 2.JVM垃圾回收种类 分为2种,Min ...

  2. JAVA虚拟机内存分配原则 (转

    Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配. 当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间, ...

  3. Java 虚拟机内存分配机制

    Java 虚拟机内存分配机制 内存区域划分 对于大多数的程序员来说,Java 内存比较流行的说法便是堆和栈,这其实是非常粗略的一种划分,这种划分的"堆"对应内存模型的 Java 堆 ...

  4. Java 虚拟机内存分配与回收策略

    垃圾收集器与内存分配策略参考目录: 1.判断 Java 对象实例是否死亡 2. Java 中的四种引用 3.垃圾收集算法 4. Java9 中的 GC 调优 5.内存分配与回收策略 一.对象优先在 E ...

  5. Java的内存分配策略有哪些_Java的内存分配策略

    简单来说,对象内存分配主要是在堆中分配.但是分配的规则并不是固定的,取决于使用的收集器组合以及JVM内存相关参数的设定 以下介绍几条基本规则(使用的ParNew+Serial Old收集器组合): 一 ...

  6. 《深入理解Java虚拟机》-----第3章 垃圾收集器与内存分配策略

    Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的"高墙",墙外面的人想进去,墙里面的人却想出来. 3.1 概述 说起垃圾收集(Garbage Collection,G ...

  7. 《深入理解java虚拟机》笔记2——GC算法与内存分配策略

    说起垃圾收集(Garbage Collection, GC),想必大家都不陌生,它是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行在JVM上的语言,如Sca ...

  8. JAVA虚拟机之垃圾收集与内存分配策略

    最近再看<深入理解JAVA虚拟机>周志明写的第二版.现将学习笔记分享出来,方便日后复习,理解有误的地方欢迎指正! 1.运行时数据区: 程序计数器:一块较小的内存空间,保存当前线程所执行的字 ...

  9. Java虚拟机-第二篇-GC算法与内存分配策略

    2019独角兽企业重金招聘Python工程师标准>>> GC引入 在Java的运行时数据区中,程序计数器.虚拟机栈.本地方法栈三个区域都是线程私有的,随线程而生,随线程而灭,在方法结 ...

最新文章

  1. BZOJ2434 [Noi2011]阿狸的打字机
  2. linux进程被中断打断,linux – 当中断处理程序被另一个中断中断时,中断上下文如何“恢复”?...
  3. wxWidgets:从互联网下载文件
  4. java方法生命周期_java – Servlet的生命周期及其方法
  5. Burpsuite工具的使用
  6. HH SaaS电商系统的拼团系统设计
  7. 【Python CheckiO 题解】First Word (simplified)
  8. 26 FI配置-财务会计-外币评估-定义评估方法
  9. 生成Treeview树 递归方法
  10. 【渝粤教育】国家开放大学2018年春季 8638-21T薪酬制度与薪酬管理 参考试题
  11. 瞬时电压示波器matlab,示波器测量瞬时电压的方法与步骤
  12. android看本地视频播放器下载,Android平台上5款最好的本地视频播放软件
  13. PHP-利用阿里云邮件推送免费发邮件详细步骤
  14. LaTeX Beamer 制作PPT时给某一页添加背景图片(并设置透明度)
  15. bartlett方差齐性检验_仅有两独立样本的样本量、均值和标准差,在SPSS进行T检验...
  16. 如何使用 win10 虚拟桌面
  17. Java是如何实现外卖订餐系统的
  18. 【NVIDIA】ubuntu桌面版安装nvidia显卡驱动程序
  19. Ubuntu18.04图标显示实时网速
  20. APP元素定位工具Weditor连接夜神模拟器

热门文章

  1. 文档类型定义和合法性(2)
  2. C#DNS域名解析工具(DnsLookup)
  3. 理解Windows窗体和WPF中的跨线程调用
  4. 批处理ping指定ip列表
  5. PHP7.2 redis
  6. jQ效果:简单的手风琴效果
  7. 不一样的视角,程序员世界里的环保
  8. IT综合学习网站收集
  9. 构建第一个Flex的Mobile APP
  10. 使用.NET Remoting开发分布式应用——基于租约的生存期(转载)