jvm虚拟机--堆内存

reserved 保留区域

所有对象实例都在这里分配内存。

是垃圾收集的主要区域("GC 堆")。现代的垃圾收集器基本都是采用分代收集算法,主要思想是针对不同的对象采取不同的垃圾回收算法。虚拟机把 Java 堆分成以下三块:

  • 新生代(Young Generation)
  • 老年代(Old Generation)
  • 永久代(Permanent Generation)

当一个对象被创建时,它首先进入新生代,之后有可能被转移到老年代中。

新生代存放着大量的生命很短的对象,因此新生代在三个区域中垃圾回收的频率最高。为了更高效地进行垃圾回收,把新生代继续划分成以下三个空间:

  • Eden(伊甸园)
  • From Survivor(幸存者)
  • To Survivor

Java 堆不需要连续内存,并且可以动态增加其内存,增加失败会抛出 OutOfMemoryError 异常。

可以通过 -Xms 和 -Xmx 两个虚拟机参数来指定一个程序的 Java 堆内存大小,第一个参数设置初始值,第二个参数设置最大值。

java -Xms=1M -Xmx=2M HackTheJava


一般来说一个新创建的对象都会被分配到eden区(一些大对象,虚拟机里有那个参数3MB会直接进老年代),些对象经过第一次Minor GC后,如果仍然存活,将会被移到Survivor区。对象在Survivor区中每熬过一次Minor GC,年龄就会增加1岁,当它的年龄增加到一定程度时,就会被移动到年老代中。

GC开始的时候,对象只会存在于Eden区和名为“From”的Survivor区,Survivor区“To”是空的。紧接着进行GCEden区中所有存活的对象都会被复制到“To”,而在“From”区中,仍存活的对象会根据他们的年龄值来决定去向。年龄达到一定值(年龄阈值,可以通过-XX:MaxTenuringThreshold来设置,默认15)的对象会被移动到年老代中,没有达到阈值的对象会被复制到“To”区域。经过这次GC后,Eden区和From区已经被清空。这个时候,“From”和“To”会交换他们的角色,也就是新的“To”就是上次GC前的“From”,新的“From”就是上次GC前的“To”。不管怎样,都会保证名为ToSurvivor区域是空的。Minor GC会一直重复这样的过程,直到“To”区被填满,“To”区被填满之后,会将所有对象移动到年老代中

这个里  网上有一个有段话就是解释这个的

我是一个普通的java对象,我出生在Eden区,在Eden区我还看到和我长的很像的小兄弟,我们在Eden区中玩了挺长时间。有一天Eden区中的人实在是太多了,我就被迫去了Survivor区的“From”区,自从去了Survivor区,我就开始漂了,有时候在Survivor的“From”区,有时候在Survivor的“To”区,居无定所。直到我15岁的时候,爸爸说我成人了,该去社会上闯闯了。于是我就去了年老代那边,年老代里,人很多,并且年龄都挺大的,我在这里也认识了很多人。在年老代里,我生活了20(每次GC加一岁),然后被回收。




永久代(perm)
 PermSpace主要是存放静态的类信息和方法信息,静态的方法和变量,final标注的常量信息等。

方法区和持久代的关系:

方法区物理上存在于堆里,而且是在堆的持久代里面;但在逻辑上,方法区和堆是独立的。
一般说堆的持久代就是说方法区,因为一旦JVM把方法区(类信息,常量池,静态字段,方法)加载进内存以后,这些内存一般是不会被回收的了。

猜你喜欢

转载自www.cnblogs.com/canacezhang/p/9333978.html