JVM专题-堆(heap)
Posted IT老刘
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM专题-堆(heap)相关的知识,希望对你有一定的参考价值。
1.定义
Heap堆
- 通过new关键字,创建对象都会使用堆内存
特点
- 它是线程共享的,堆中对象都需要考虑线程安全的问题
- 有垃圾回收机制
2.堆内存溢出
OutOfMemoryError:java heap space 堆内存溢出
堆空间调整参数
-Xmx空间大小
-Xmx4G
案例
package com.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 = "hello";
while (true) {
list.add(a); // hello, hellohello, hellohellohellohello ...
a = a + a; // hellohellohellohello
i++;
}
} catch (Throwable e) {
e.printStackTrace();
System.out.println(i);
}
}
}
结果:
java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:421)
at java.lang.StringBuilder.append(StringBuilder.java:136)
at com.heap.Demo1_5.main(Demo1_5.java:19)
26
在实际生产中,对于堆内存溢出问题,可能宾士那么容易检测出来。因为堆内存空间比较大,在运行时,一时间还不会使其溢出。
所以为了使堆内存问题尽早暴露出来,可以在测试时,将堆内存空间调整小一些。
3.堆内存诊断
- jps工具
查看当前系统中有哪些java进程 - jmap工具
查看某一时刻堆内存占用情况
jmap -heap 进程id
- jconsole工具
图形界面的,多功能的监测工具,可以连续监测
堆内存调整指令参数
-Xmx容量
3.1.jmp诊断堆内存
案例代码
/**
* 演示堆内存
*/
public class Demo1_4 {
public static void main(String[] args) throws InterruptedException {
System.out.println("1...");
Thread.sleep(30000);
byte[] array = new byte[1024 * 1024 * 10]; // 10 Mb
System.out.println("2...");
Thread.sleep(20000);
array = null;
System.gc();
System.out.println("3...");
Thread.sleep(1000000L);
}
}
Thread.sleep 是为了留有时间间隔执行命令,监控进程状态
程序打印 1… 后,执行jps查看该进程的进程号
jmap -heap 进程id
,查看这一时刻进程堆空间使用情况
程序打印 2… 后,再次执行 jmap 指令查看内存情况
程序打印 3… 后,再次执行 jmap 指令查看内存情况
程序运行后
8776为该进程的pid,调用命令
具体的堆内存占用在Heap Usage
在程序打印了 2… 后,再次
在打印了 3… 之后,代表着已经被垃圾回收了
3.2.jconsole诊断堆内存
但是在jconsole里面可以看出,在给array初始化后,堆内存使用量增加了10M,在垃圾回收后,堆内存使用量又迅速下降。
3.3.jvisualvm诊断堆内存
jvisualvm是功能更加强大的图形化jvm管理软件。可以进行堆转储,拿到进程某一时刻的快照dump进行分析。
案例代码:
package com.heap;
import java.util.ArrayList;
import java.util.List;
/**
* 演示查看对象个数 堆转储 dump
*/
public class Demo1_13 {
public static void main(String[] args) throws InterruptedException {
List<Student> students = new ArrayList<>();
for (int i = 0; i < 200; i++) {
students.add(new Student());
// Student student = new Student();
}
Thread.sleep(1000000000L);
}
}
class Student {
private byte[] big = new byte[1024*1024];
}
经过测试,在执行了垃圾回收后,堆内存占用还是居高不下。
于是点击 堆dump 拿取快照,分析详情
点击查看
由源代码可知,确实是Student类的原因。
student数组一直在循环引用,没有被垃圾回收。
以上是关于JVM专题-堆(heap)的主要内容,如果未能解决你的问题,请参考以下文章
JVM技术专题让你完全攻克内存溢出(OOM)这一难题「案例篇」
Java技术专题-JVM研究系列(26)让你完全攻克内存溢出(OOM)这一难题