美文网首页
内存分配与回收

内存分配与回收

作者: T_log | 来源:发表于2018-08-09 15:18 被阅读15次

概述

  1. java技术体系所提倡的自动内存管理其实主要包括 ①:给对象分配内存 ②:回收给对象分配的内存
  2. 对象的内存分配大部分情况下指的是在堆上分配(也可以经过JIT即时编译后被拆散为标量类型并间接的栈上分配)
  3. 对象主要在新生代的Eden上进行分配
  4. 少数情况下会直接在老年代上进行内存分配
  5. 分配规则是由采用哪种垃圾收集器组合和虚拟机中与内存相关的参数设置

对象优先在Eden上分配

  1. 大多数情况下,对象优先在Eden上进行内存分配,当Eden内存不足时,虚拟机将发起一次Minor GC
  2. 新生代GC (Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多数都是朝生夕死,所以Minor GC会非常的频繁,回收速度也比较快
  3. 老年代GC(Major GC/Full GC);指发生在老年代的GC,出现了Major GC经常会伴随至少一次的Minor GC(也非绝对),速度上会比Minor GC慢10倍以上

大对象直接进入老年代

  1. 所谓大对象,是指需要大量连续的内存空间,典型的大对象就是很长的字符串和数组
  2. 在应用程序中,应尽量避免朝生夕死的大对象
  3. JVM提供了-XX:PretenureSizeThreshole参数,凡是大于这个参数的对象直接进行老年代,避免GC时,新生代中从Eden复制到Survivor区中时,因为Survivor没有足够的空间存放该对象,从而触发一次GC
  4. PretenureSizeThreshole只对Serial和ParNew两种收集器起作用,Parallel Scavenge收集器不认识这个参数

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

  1. JVM给每个对象定义了一个年龄,如果在Eden中经历过一次Minor后,对象被移植到Survivor中,且Survivor能够容纳的话,对象年龄设为1,且没熬过一次Minor GC,年龄就加一
  2. 当对象的年龄增加到一定程度(默认15),就会晋升到老年代
  3. 对象晋升到老年代的年龄阈值,可以通过参数-XX:MaxTenuringThreshold设置

空间分配担保

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

参考
周志明《深入理解Java虚拟机》

写在最后
做一个灵魂和肉体分离的人,灵魂不受肉体的束缚,灵魂可以指挥肉体

相关文章

网友评论

      本文标题:内存分配与回收

      本文链接:https://www.haomeiwen.com/subject/xnxcbftx.html