JVM结构

JVM结构
JVM结构
JVM分为三代:年轻代(Young Generation)、年老代(Old Generation)、持久代(Permanent Generation)。之所以分成三代是为了更好的处理内存。 年轻代:年轻代分为三个区:一个eden区和两个Survivor区。程序首先运行时是在eden区运行,如果eden区存满了对对象,那么就复制到Survivor区。先将存活对象复制到第一个Survivor区即S0,如果第一个Survivor区也存满了那么就会复制第二个Survivor区即S1。如果第二个Survivor区也存满了,那么就会将对象复制到年老代(Old Generation)。 年老代就是处理在年轻代中通过GC回收机制后还存活的对象

持久代主要是存放一些静态的方法、类等。所以持久代GC内存回收并没有明显效果。 JVM之所以需要分代,是为了更好的去使用内存,让内存的使用效率达到最佳,当然分代之后就需要对不同的代采用不同的收集方式,对其内存进行回收。 由于程序在运行过程会使用到很基本类型的和引用数型数据,如session对象、socket对象等。而这些对象可数据其生存期是不一样的,所以最后在程序运行会将这些不同的对象划分到不同代中,然后不同的代使用不同收集内存方式。

在java 8之前JVM第三代都是持久代PermGen,在java 8和之后的版本都是Metaspace元空间。
JVM结构
JVM在运行时,将分内存划分为heap memory和non-heap memory两类。

在JVM使用年轻代和年老都在heap memory。

meatspace、thread等都是在non-heap memory。

将PermGen持久代换成Metaspace元空间主要是优化以下几个问题:

1.字符串变化问题

以前的版本中PermGen会存储一些字符串,PermGen内存的大小是通过-xx:PermSize这个参数来设置的,但是由于字符串池的大小经常是变化的,导致设置-xx:PermSize这个参数变的困难,这样很容易出现OOM提示的错误 ,java.lang.OutOfMemoryError: PermGen space。

java 8之后是将字符串对象放在堆内存。这样避免OOM问题的出现。

2.方法区变化

以前将方法主要存储在PermGen,现在将方法都移动Metaspace,Metaspace不在JVM中,而是在本地的内存。