问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

Java内存分配与回收策略

发布网友 发布时间:2024-10-01 07:13

我来回答

1个回答

热心网友 时间:2024-11-30 17:07

对象的内存分配,就是在堆上分配(也可能经过 JIT 编译后被拆散为标量类型并间接在栈上分配),对象主要分配在新生代的 Eden 区上,少数情况下可能直接分配在老年代,分配规则不固定,取决于当前使用的垃圾收集器组合以及相关的参数配置。

以下列举几条最普遍的内存分配规则。

对象优先在 Eden 分配

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

Minor GC vs Major GC/Full GC:

Minor GC:回收新生代(包括 Eden 和 Survivor 区域),因为 Java 对象大多都具备朝生夕灭的特性,所以 Minor GC 非常频繁,一般回收速度也比较快。

Major GC / Full GC: 回收老年代,出现了 Major GC,经常会伴随至少一次的 Minor GC,但这并非绝对。Major GC 的速度一般会比 Minor GC 慢 10 倍 以上。

在 JVM 规范中,Major GC 和 Full GC 都没有一个正式的定义,所以有人也简单地认为 Major GC 清理老年代,而 Full GC 清理整个内存堆。

大对象直接进入老年代

大对象是指需要大量连续内存空间的 Java 对象,如很长的字符串或数据。一个大对象能够存入 Eden 区的概率比较小,发生分配担保的概率比较大,而分配担保需要涉及大量的复制,就会造成效率低下。

虚拟机提供了一个 -XX:PretenureSizeThreshold 参数,令大于这个设置值的对象直接在老年代分配,这样做的目的是避免在 Eden 区及两个 Survivor 区之间发生大量的内存复制。(还记得吗,新生代采用复制算法回收垃圾)

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

JVM 给每个对象定义了一个对象年龄计数器。当新生代发生一次 Minor GC 后,存活下来的对象年龄 +1,当年龄超过一定值时,就将超过该值的所有对象转移到老年代中去。

使用 -XXMaxTenuringThreshold 设置新生代的最大年龄,只要超过该参数的新生代对象都会被转移到老年代中去。

动态对象年龄判定

如果当前新生代的 Survivor 中,相同年龄所有对象大小的总和大于 Survivor 空间的一半,年龄 >= 该年龄的对象就可以直接进入老年代,无须等到 MaxTenuringThreshold 中要求的年龄。

空间分配担保

JDK 6 Update 24 之前的规则是这样的:

在发生 Minor GC 之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间, 如果这个条件成立,Minor GC 可以确保是安全的; 如果不成立,则虚拟机会查看 HandlePromotionFailure 值是否设置为允许担保失败, 如果是,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小, 如果大于,将尝试进行一次 Minor GC,尽管这次 Minor GC 是有风险的; 如果小于,或者 HandlePromotionFailure 设置不允许冒险,那此时也要改为进行一次 Full GC。

JDK 6 Update 24 之后的规则变为:

只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小,就会进行 Minor GC,否则将进行 Full GC。

通过清除老年代中的废弃数据来扩大老年代空闲空间,以便给新生代作担保。

这个过程就是分配担保。

可能会触发 JVM 进行 Full GC的情况

System.gc() 方法的调用此方法的调用是建议 JVM 进行 Full GC,注意这只是建议而非一定,但在很多情况下它会触发 Full GC,从而增加 Full GC 的频率。通常情况下我们只需要让虚拟机自己去管理内存即可,我们可以通过-XX:+ DisableExplicitGC 来禁止调用System.gc()。

老年代空间不足 老年代空间不足会触发 Full GC 操作,若进行该操作后空间依然不足,则会抛出如下错误:java.lang.OutOfMemoryError: Java heap space

永久代空间不足 JVM 规范中运行时数据区域中的方法区,在 HotSpot 虚拟机中也称为永久代(Permanet Generation),存放一些类信息、常量、静态变量等数据,当系统要加载的类、反射的类和调用的方法较多时,永久代可能会被占满,会触发 Full GC。如果经过 Full GC 仍然回收不了,那么 JVM 会抛出如下错误信息:java.lang.OutOfMemoryError: PermGen space

CMS GC 时出现 promotion failed 和 concurrent mode failure promotion failed,就是上文所说的担保失败,而 concurrent mode failure 是在执行 CMS GC 的过程中同时有对象要放入老年代,而此时老年代空间不足造成的。

统计得到的 Minor GC 晋升到旧生代的平均大小大于老年代的剩余空间。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
预算2000内的手机2000元以内双核手机 我女儿被摩托车一撞伤后,骑车人逃逸了,记住车牌号报警后,找到车主... ...擦车事件.给钱私了对方写了协议书和收据.但肇事局把车拖走了... 我被摩托车撞了对方是全责,头部还缝了六针,我可以要求赔偿多少?_百度... 对方醉酒驾摩托车撞伤家人,现在想出院静养,赔偿事宜该怎么协商,应该赔 ... 摩托车追尾我家人的车,摩托车司机骨折,交警扣了我家的车 现在需要我们... outlook 资料怎么转移到其他电脑上 正规废镍回收联系方式 手机用音乐播放器那个更好? 哪种播放器音质最好 97年深圳黄金多少钱一克 2寸电子照片怎么制作? 翡翠玉石的种类和区别 怎么样设置微信不让好友看战绩 想考导游证可以自己看书自考么还是一定要去上培训班?考导游高中学历可以... 怎么样自考导游证啊,不参加培训班的那种 在南京考导游证(国导),书一定要在培训的地方买吗?怎么报名 考导游证需要那些书啊,还有不上辅导班可以过吗 去寒姜茶有哪些做法呢 驱寒姜茶怎么做 驱寒红糖姜茶怎么做 苹果7可以升级ios14 ...都不懂,什么都没有学会,一无是处,该怎么办? 微博密码怎么改? 反渗透净水器和超滤净水器的区别在哪里呢 反渗透净水器和超滤净水机有什么区别? 摩卡婚礼策划馆摩卡总裁 不拆机如何清理笔记本灰尘? 摩卡婚礼摩卡团队 人类的极限是多少米? Hotpot Java虚拟机Class对象是在方法区还是堆中 JVM内存区域划分Eden Space、Survivor Space等详解和回收过程 【金三银四】JVM虚拟机CMS和G1收集器详解 青岛有哪些设计公司 梦见自己快要死了, 上午家人把我出殡送到坟地,打算下午把我埋了,我... 青岛盛世天彩品牌策划有限公司怎么样? 青岛艺陆彩东道品牌策划有限公司怎么样 零食品牌想升级一下LOGO,可爱的 卡通的,最好还能设计下卡通形象,有青岛... 九月你好的唯美句子 2019九月你好唯美心情说说 青岛灵沃品牌策划有限公司怎么样? 青岛米恩品牌策划有限公司怎么样? ...4A 级广告公司?奥美广告 在青岛有分布没有? 我女儿十一岁了,总是想男女之间的事,我该如何教育 油豆腐干锅怎么做好吃 热水器或电动车充电器线路板有高低压分区吗 儿童叛逆期的孩子怎么去引导? 我是男的的一到天气凉的的时候特别在冬天手脚就会很冰,请问是什么回事... ...我曾经忍不住打骂她,因为她的行为态度很恶劣,我该如何和她... ...女儿表面上很怕我,可实际上特别是叛逆,我该怎么管? 小女孩不听话怎么教育小女孩不听话如何教育