一、Java虚拟机内存结构图
二、堆的介绍
1. 前面学习的程序计数器,虚拟机栈和本地方法栈都是线程私有的,堆是线程共享的;
2. 通过 new 关键字,创建的对象都会使用堆内存,其特点是:
-
它是线程共享的,堆中对象都需要考虑线程安全的问题(虚拟机栈中的局部变量只要不逃离方法的作用范围就是线程安全的 )
-
有垃圾回收机制
三、一些示例
3.1 堆内存溢出
1. 代码示例
package cn.itcast.jvm.t1.heap;
import java.util.ArrayList;
import java.util.List;
/**
* 演示堆内存溢出 java.lang.OutOfMemoryError: Java heap space
* -Xmx8m
*/
public class Demo1_5 {
public static void main(String[] args) {
int i = 0;
try {
List<String> list = new ArrayList<>();
String a = "hahaha";
while (true) {
list.add(a); // hahaha, hahahahahaha, hahahahahahahahaha...
a = a + a;
i++;
}
} catch (Throwable e) {
e.printStackTrace();
System.out.println(i);
}
}
}
2. 报错信息
3. 修改堆内存大小
修改了堆内存大小后再次运行程序:
3.2 堆内存诊断工具
jps: 首先通过jps工具查看当前系统中有哪些Java进程
jmp: 拿到Java进程后,可以通过jmap工具查看某个java进程的堆内存的使用情况,注意:jmpa只能查询某个时刻堆内存的占用情况,如果想对 堆内存做一个连续的检测,需要使用jmap或jvirsualvm工具:
jconsole:
jvirsualvm: