编程语言
首页 > 编程语言> > Java堆详解

Java堆详解

作者:互联网

Java堆

堆的对象管理

堆的概述

  1. 一个JVM进程存在一个堆内存,堆是JVM内存管理的核心区域
  2. Java堆区在JVM启动时被创建,其空间大小也被确定,是JVM管理的最大一块内存(堆的大小可以调整)
  3. 本质上堆是一组在物理上不连续的内存空间,但是逻辑上是连续的空间(参考HSDB分析的内存结构)
  4. 所有线程共享堆,但是堆内对于线程处理还是做了一个线程私有的部分(TLAB)

堆内存的细分

堆空间的分代思想

老年代,年轻代,永久代
为什么需要分代?有什么好处?

堆的默认大小

初始大小:电脑物理内存/ 64
最大内存大小:电脑物理内存 / 4

RunTime类

该类对应JVM的运行时数据区

long initialMemory = Runtime.getRuntime().totalMemory();
long maxMemory = Runtime.getRuntime().maxMemory();
long freeMemory = Runtime.getRuntime().freeMemory();

堆区详解

对象在堆区中的位置变化

这里上两张图结构图:

年轻代又分为Eden区和survivor区,
1.所有对象一出生都会在Eden区,并且对象年龄为0。Eden区满了之后会触发minor GC, minor GC只回收年轻代中需要回收的对象。每一次minor GC,若该对象没有被回收,那么对象的年龄就会 + 1。对象到达阈值以后该对象会进入老年代(android阈值为6)
2.当老年代空间满了以后会触发full GC,full GC会同时回收年轻代和老年代中所有需要回收的对象

minor GC

Eden区满了以后,会调用minor GC,该GC只会回收年轻代中需要回收的对象,然后对不可回收的对象进行标记(就是把不可回收对象的年龄 + 1),对象年龄达到阈值后对象会进入老年代空间

full GC

当老年代空间满了以后会触发full GC,full GC会回收年轻代和老年代中所有需要回收的对象

相关命令

jps ,查看当前所有java进程id

jstat -gc 进程id 查看

Eden区:

对象一创建就会位于该区

Survivor区:
Survivor区的作用:
对象在年轻代位置的变化:
  1. 对于一个刚刚创建的对象A,它一开始位于Eden区

  2. 第一次minor GC触发,如果它没被回收,它会进入S0区,并且A年龄 + 1

  3. 第二次minor GC触发,如果它没被回收,它会进入S1区,并且A年龄 + 1

  4. 第三次minor GC触发,如果它没被回收,它会进入S0区,并且A年龄 + 1

  5. 第四次minor GC触发,如果它没被回收,它会进入S1区,并且A年龄 + 1

  6. 第....次 ,当A年龄达到阈值,进入老年代

  1. Eden区满后,触发第一次minor GC,对Eden区进行对象回收(第一次minor GC时候survivor0和survivor2区都是空的,所以只回收Eden区),回收后Eden区中的存活对象的内存不再连续,此时将所有的存活对象移到Survivor0区中内存连续的空间
  2. Eden区又满后,触发第二次minor GC,对Eden区和Survivor0区进行对象回收(Survivor1区是空的,所以不用回收),回收后Eden区和survivor0区中的存活对象内存可能不再连续,此时会将所有的存活对象移动到Survivor1区中内存连续的空间
  3. Eden区再次满了后,触发第三次minor GC,对Eden区和Survivor1区进行对象回收(Survivor0区是空的,所以不用回收),回收后Eden区和survivor1区中的存活对象内存可能不再连续,此时会将所有的存活对象移动到Survivor0区中内存连续的空间
  4. Eden区满,触发第N次GC.......................
  5. 之后存活对象会不断在Survivor0区和Survivor1区中切换,直到年龄达到阈值后进入老年代

标签:Java,Eden,对象,回收,详解,GC,内存,minor
来源: https://www.cnblogs.com/shzy-android/p/15832293.html