JVM内存划分

JVM内存划分

一、内存区域的划分

1.1 程序计数器

每个线程都有自己的程序计数器,主要用来存储其正在执行的方法地址;

1.2 Java虚拟机栈

每个线程都会创建一个自己的虚拟机栈,其内部保存一个个的栈帧,对应一次次的方法调用;

1.3 本地方法栈

每个线程都会创建一个本地方法栈,用来保存对本地方法的调用;

1.4 堆

堆是所有线程共享的区域,所有的Java对象实例都是存放在这里的。垃圾收集器需要对堆进行管理,因此会分为新生代和老年代;其中新生代又分为Eden区和Survivor区。

1.5 方法区

也是所有线程共享的区域,存储一些元信息,主要是类的结构信息、常量池等;

二、堆内部结构详解

2.1 新生代

绝大部分的对象都是在新生代完成创建和销毁的,它们的生命周期往往都很短暂。

  • Eden区,作为对象初始分配的区域;
  • Survivor-from区,存放从MinorGC中保留下来的对象;from区和to区是相互转化的;
  • Survivor-to区,存放从MinorGC中保留下来的以及Survivor-from区的全部对象;之所以要拷贝Survivor-from区的对象,是为了避免出现内存的碎片化;

2.2 老年代

Survivor-to区的对象经过一定的年龄,会被转移到老年代;

如果新创建的对象比较大,在新生代找不到合适的空间,就会被直接创建在老年代;

2.3 永久代

早期JVM会在永久代存放类的元数据,常量池等,现在永久代取消了,这部分数据都放在了方法区;

三、堆大小的设置

  • 设置最大堆体积

    -Xmx value

  • 设置初始最小堆体积

    -Xms value

  • 设置老年代和新生代的比例

    -XX:NewRatio=value

    默认值是2,即老年代是新生代的2倍;

  • 设置新生代的体积

    -XX:NewSize=value

  • 设置Eden区和Survivor区的大小

    -XX:SurvivorRatio=value

    Eden区和Survivor区是存在比例关系的,Survivor区是Eden区的1/value大小;

你可能感兴趣的:(JVM内存划分)