4.3 对象分配过程
- new对象时首先会将对象放在eden区,该区大小有内存限制 。
- 当eden区的数据满了之后,程序还需要创建对象,会触发垃圾回收,将那些不再被引用的对象给销毁掉 。
- 剩余没被回收掉的对象会被转移到S0区,而程序新创建的对象又会继续写入Eden区 。
- 当再次发生垃圾回收时,如果S0中还存在未被销毁的对象,那么这部分剩余的对象会被转移到S1中 。
- 之后每次经历垃圾回收,存在S0或者S1中未被销毁的对象总会相互转移过去 。
- 当这种转移达到15次上限后,那么这部分对象将会被转移到老年区 。当然这个阈值并不是固定15,可以通过调节参数 -XX:MaxTenuringThreshold=N来控制阈值 。
- 当养老区的内存也不足时,会触发GC进行养老区的垃圾回收 。
- 如果养老区进行了GC垃圾回收后还是没有办法保存新创建的对象,那么将会报OOM异常 。
部分收集
- 新生代收集(Minor GC/Yong GC):只是新生代的垃圾回收 。
- 老年代收集(Major GC/Old GC):只是老年代的垃圾回收 。
- 混合收集(Mixed) :收集整个新生代和老年的垃圾 。(G1 GC会混合回收, region区域回收)
年轻代GC触发条件
- 当年轻代内存不足时,会触发Minor GC,这里的内存不足指的是Eden区的内存不足,Survivor区不会 。
- Minor GC 会暂停其他用户的线程,等到垃圾回收结束,用户的线程才恢复 。
- 老年代空间不足时,会尝试触发Minor Gc,如果空间还是不足,则会触发Major GC
- 如果Major GC结束后,空间还是不足,会报OOM异常 。
- Major GC的速度比Minor GC慢10倍以上 。
- 程序调用System.gc(),会触发Full GC,但不会立即去执行 。
- 老年代空间不足 。
- 方法区空间不足 。
- 通过Minor GC后仍能进入老年代的对象所占空间大于老年代剩余可用空间 。
- 在之前的永久代中,它是堆的一部分,主要是在存储类的元数据、静态变量、常量等,这些数据的大小也不太容易控制和计算,开发人员对永久代进行调优会有很多的难度 。永久代会对GC带来不必要的复杂度,回收效率偏低 。
- 而用元空间替代永久代,这样的话可以很好的解决这个问题,因为元空间是放在本地内存上的,简而言之,只要你服务器内存还有,元空间基本就不会发生内存溢出等问题 。
- 由于类的元数据分配在本地内存上,这样就说元空间的最大分配内存就是服务器系统剩余可用内存,不会遇到永久代时存在的内存溢出问题 。
- 将运行时常量池从永久代中分离出来,与类的元数据分开,提高了元数据的独立性 。
- 将元数据从永久代剥离出来放到元空间,可以提升对元数据的管理,同时也提升GC效率 。
- -XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值 。
- -XX:MaxMetaspaceSize,最大空间,默认是没有限制的 。如果没有使用该参数来设置类的元数据的大小,其最大可利用空间是整个系统内存的可用空间 。JVM也可以增加本地内存空间来满足类元数据信息的存储 。但是如果没有设置最大值,则可能存在bug导致Metaspace的空间在不停的扩展,会导致机器的内存不足;进而可能出现swap内存被耗尽;最终导致进程直接被系统直接kill掉 。如果设置了该参数,当Metaspace剩余空间不足,会抛出:java.lang.OutOfMemoryError: Metaspace space 。
经验总结扩展阅读
- 【JVM】关于JVM,你需要掌握这些 | 一文彻底吃透JVM系列
- JVM学习笔记——垃圾回收篇
- OPPOK9Pro参数_OPPOK9Pro详细参数配置
- oppoa93s参数详细_oppoa93s参数配置详情
- 【Bluetooth蓝牙开发】一、开篇词 | 打造全网最详细的Bluetooth开发教程
- Nokia C20 Plus评测_Nokia C20 Plus详细评测
- 时序数据库TDengine详细安装+集成流程+问题解决
- 为什么说端午节寒气最重 这3个角度解析原因你要了解
- iqooz1参数配置详情_vivoiqooz1参数详细参数配置
- JVM学习笔记——内存结构篇