一个进程对应一个 JVM 实例,一个 JVM 实例对应一个运行时数据区。
概述
- Java堆区在JVM启动的时候即被创建,其空间大小也就确定了,堆是JVM管理的最大一块内存空间,并且堆内存的大小是可以调节的
- 所有的线程共享Java堆,在这里还可以划分线程私有的缓冲区(Thread Local Allocation Buffer,TLAB)
- 几乎所有的对象实例以及数组都应当在运行时分配在堆上
- 栈、堆、方法区的关系:
- 在方法结束后,堆中的对象不会马上被移除,仅仅在 GC 的时候才会被移除
- 堆,是GC(Garbage Collection,垃圾收集器)执行垃圾回收的重点区域
- 内存细分
- Java7:新生区+养老区+永久区
- Java8:新生区+养老区+元空间
- 新生区又被划分为Eden区和Survivor区
设置堆内存大小及OOM
设置堆内存大小
如何设置
- -Xms用于表示堆区的起始内存,等价于 -XX:InitialHeapSize
- -Xmx则用于表示堆区的最大内存,等价于 -XX:MaxHeapSize
为什么Xms Xmx一般设置成相等
- 频繁的扩容和释放造成不必要的压力
默认情况下的堆内存
- 初始内存大小:物理电脑内存大小/64
- 最大内存大小:物理电脑内存大小/4
如何查看设置的参数
- 方式一:cmd ===> jps / jstat -gc 进程id
- 方式二:idea 设置 ===> -XX:+PrintGCDetails
为什么加起来的总内存小于设置的堆内存
- S0区和S1区两个只有一个能使用
OOM
一旦堆区中的内存大小超过“-Xmx"所指定的最大内存时,将会抛出OutofMemoryError异常。
新生代与老年代
划分
内存参数
- 新生代与老年代比例:-XX:NewRatio
- 默认为2
- -Xmn:设置新生代的空间的大小,同时设置 -XX:NewRatio 与 -Xmn 时,会选择 -Xmn(一般不用 -Xmn)
- Eden空间和另外两个survivor空间比例:-XX:SurvivorRatio
- 默认是8
- 实际看内存的时候比例并不是 8:1:1
- -XX:-UseAdaptiveSizePolicy :关闭自适应的内存分配策略(暂时用不上)
- -XX:SurvivorRatio:指定