Java 堆是虚拟机所管理的内存中最⼤的⼀块,Java 堆是所有线程共享的⼀块内存区域,在虚拟机启动时创建。此内存区域的唯⼀⽬的就是存放对象实例,⼏乎所有的对象实例以及数组都在这⾥分配内存
1.通过new关键 ,创建的对象存放在堆中;
2.所有线程会共享到同一个堆内存;
3.在堆内存中是有垃圾回收机制的;
堆内存泄漏问题
内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
内存泄漏: 创建了很多对象存放在堆内存中,GC回收了很多次就是无法清理该垃圾对象。
/**
* 演示堆内存溢出 -Xmx8m
*
* @param args
*/
public static void main(String[] args) {
List list = new ArrayList<>();
while (true) {
list.add(new UserEntity());
}
}
public class UserEntity {
// 申请 1mb 空间
private byte[] mayiktByte = new byte[1024 * 1024];
}
如下示例:
bytes 如果不设置为null , 就会一直占用空间,就算主动 System.gc(),也无法清理
public static void main(String[] args) throws InterruptedException {
System.out.println("1"); // 堆内存 假设 5mb
Thread.sleep(1000 * 30); // 阻塞30s
byte[] bytes = new byte[1024 * 1024 * 10];// 申请10mb内存
System.out.println("2"); // 堆内存 假设 15mb
Thread.sleep(1000 * 30); // 阻塞30s
bytes = null; // null GCRoot 引用链
System.gc(); // 主动调用GC方法 不会立即清理 堆内存垃圾 通知作用
System.out.println("3"); // gc回收 15-10mb 5mb左右
Thread.sleep(1000 * 10000);
}
其他:
内存溢出 一般都是 内存泄漏从而导致的问题, gc回收垃圾对象就是无法回收,在从新向堆内存申请,新的内存存放对象没有空间可以使用
内存溢出(Out Of Memory)应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于能提供的内存。
Win操作系统打开任务管理系统 查看到那个进程占用cpu比较高即可
Linux 可使用arthas(阿尔萨斯) 排查cpu飙高的问题
# 1.下载阿尔萨斯
curl -O https://arthas.aliyun.com/arthas-boot.jar
2. java -jar arthas-boot.jar
3. 选择运行的基础进程 输入1
4. thread -n 3
1.Jps 查看当前系统中有哪些Java进程
需安装 jdk
jps # 查看当前系统中有哪些Java进程
jmap -heap 进程id # 查看堆内存占用情况
jdk 安装目录下
使用 Jvisualvm
查看最大占用的内存