文章目录
1. 堆的核心概述
-
一个进程对应一个JVM实例,一个JVM实例只存在一个堆内存。
-
java堆区在JVM启动时就被创建,其空间大小就被固定了。
-
堆内存大小是可以调节的。
-
《Java虚拟机规范》规定,堆可以在物理上不连续空间。但在逻辑上它是连续的。
-
所有线程共享Java堆,在这里还可以划分线程私有的缓冲区(Thread Local Allocation Buffer,TLAB)下面第10大点会详细讲到。
-
在《Java虚拟机规范》中描述:所i有对象以及数组都对应在运行时分配的堆上。但是有例外,有可能Java虚拟机栈也会存储对象。
-
栈帧中保存着的引用会指向对象或者数组在堆中的位置
-
在方法结束后,堆中的对象不会马上被移除,仅仅在垃圾收集的时候才会被移除。
-
堆,是GC(Carbage Collection)执行垃圾回收的重点区域。
堆的核心概述:内存分析
2.设置堆内存大小与OOM
(1)堆空间大小的设置
- 参数为:
“-Xms” :用来设置堆(年轻区+老年区)的初始内存大小。等价于-XX:InitialHeapSize
“-Xmx” :用来设置堆(年轻区+老年区)的最大内存。 等价于-XX:MaxHeapSize
默认情况下:堆的初始内存大小:电脑物理内存的1/64;
默认情况下:堆的最大内存大小:电脑物理内存的1/4;
在开发中我们通常将堆内存初始值和最大值相等;
原因:如果不一样,如果程序运行期间堆内存不够,堆会扩容,从而浪费资源去扩容。
下面我用堆内存默认设置:我的内存大小为8G
public class HeapSpaceInitial {
public static void main(String[] args) {
//返回Java虚拟机中的初始堆内存总量
long l = Runtime.getRuntime().totalMemory()/1024/1024;
//返回Java虚拟机中的最大堆内存总量
long l1 = Runtime.getRuntime().maxMemory()/1024/1024;
System.out.println("-Xms : "+l+"M");
System.out.println("-Xms : "+l1+"M");
}
}
看出我们的堆内存初始值为117M小于8G/64;1719M小于8G/4;
原因分析:
- 设置参数:
-XX:+PrintGCDetails
2. 再看运行结果:
3.结论:年轻区中有5120k的内存大小没有使用,所以总的空间
(2)OOM(OutOfMemoyr)举例
import java.util.ArrayList;
import java.util.Random;
public class OOMTest {
public static void main(String[] args) {
ArrayList<Picture> list = new ArrayList<>();
while(true){
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
list.add(new Picture(new Random().nextInt