堆
多个线程共享一个堆空间。
一个JVM实例值存在一个堆内存,堆是内存管理的核心区域。
堆是JVM管理的最大一块空间。
堆可以处于物理上不连续的内存空间,但逻辑上他应该被视为连续。
堆内的缓冲区(TLAB)是线程私有的。
几乎所有的对象实例都在这里分配,栈中存放的是变量的引用地址。
在方法结束后,堆中的实例不会马上被移除,仅仅在垃圾收集的时候才会被移除。
堆,是执行垃圾回收的重点区域。
堆在jdk8之前和jdk8之后有什么变化?
在Java6版本中,永久代在非堆内存区;到了Java7版本,永久代的静态变量和运行时常量池被合并到了堆中;而到了Java8,永久代被元空间取代了,元空间存储静态变量和运行时常量池与Java7的永久代一样,都移到了堆中。
堆空间 = 年轻代+老年代
年轻代(Eden、from、to)
几乎所有的java对象都是在伊甸园区(Eden)被new出来的。
绝大部分的java对象销毁都是在新生代进行的。
如果对象太大,会直接被分配到老年代。
老年代
老年代主要用来存放应用中生命周期长的内存对象。老年代会比较稳定,不会频繁的进行MajorGC。
图解对象分配的过程
- new的对象先放伊甸园区。此区有大小限制。
- 当伊甸园空间填满时,程序又需要创建对象,JVM的垃圾回收器将对伊甸园区进行垃圾回收(Minor GC/YGC),将伊甸园区中的不再被其他对象所引用的对象进行销毁。再加载新的对象到伊甸园区。
- 然后将伊甸园中的剩余对象移动到幸存者0区。
- 如果再次触发垃圾回收,此时上次幸存下来的放到幸存者0区的,如果没有被回收,就会被放到幸存者1区。
- 如果再次经历垃圾回收,此时会重新放回幸存者0区,接着再去幸存者1区。
- 啥时候可以区养老区?可以设置次数,