内存结构
本地方法栈
给本地方法提供内存空间,关键字:native
堆
通过new关键字,创建对象都会使用堆内存
特点
- 它是线程共享的,堆中对象都需要考虑线程安全的问题
- 有垃圾回收机制
堆内存溢出
java中的内存溢出错误:java.lang.OutOfMemoryError: Java heap space
案例:
/*演示堆内存溢出*/
public class Demo_01 {
public static void main(String[] args) {
int i=0;
try {
List<String> list=new ArrayList<String>();
String a = "hello";
while (1==1){
list.add(a);
a=a+a;
i++;
}
}catch (Throwable e){
e.printStackTrace();
System.out.println(i);
}
}
}
在idea中设置堆空间的最大值:编辑配置,找到VM options输入参数-Xmx+要设置的堆空间大小,如果没有VM options,需要在修改选项内调出VM options
堆内存诊断
- jps工具
查看当前系统中有哪些java进程 - jmap工具
查看堆内存占用情况(只能查看某一时刻) - jconsole工具
图形界面的,多功能的监测工具,可以连续监测
监测案例代码:
/*测试堆内存工具使用*/
public class Demo_02 {
public static void main(String[] args) throws InterruptedException {
System.out.println("1...");
Thread.sleep(50000);
byte[] bytes = new byte[1024 * 1024 * 10];
System.out.println("2");
Thread.sleep(50000);
bytes=null;
System.gc();
System.out.println("3..");
Thread.sleep(100000000);
}
}
监测方法,在idea中的终端输入jps,查找对应的项目进程号吗,然后使用jmap -heap 进程号,查看相关信息,如果报Cannot connect to core dump or remote debug server. Use jhsdb jmap instead
错误,则需改成 jhsdb jmap --heap --pid 进程号
,如果报java.lang.RuntimeException: can't determine target's VM version : field "_reserve_for_allocati on_prefetch" not found in type ThreadLocalAllocBuffer
错误,则需要更换jdk版本,该问题是由于 JDK 的 bug 导致的,在 JDK9 中已经解决了该问题。
命令成功后截图:
jconsole工具的使用:
在idea终端输入jconsole,选择要连接的项目,然后就会出现如所示的界面
案例:垃圾回收后,内存占用仍然很高
另一个工具:jvisualvm,可视化展示虚拟机内容,打开界面如下图所示(jdk9版本后就不自带了,需要自行下载)
查看堆转储 dump,可以查看内存分配以及类中的内存使用