分析Java的内存溢出问题(OutofMemory)

我们开发一个测试程序,来模拟OutofMemory情况。

程序很简单,代码如下:

import java.util.ArrayList;
import java.util.List;
 
public class Test {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
 
        while(true){
            list.add(new String("test"));
        }
    }
}


我们进入该java文件所在的目录,然后打开控制窗口,进入到该目录。

通过javac编译Test.java文件

再来看我们的test目录

这下子生成了编译之后的.class文件,然后我们来执行它。

javac 编译时常见问题

javac编译时编码错误(编码格式不一致)_张某某啊哈的博客-CSDN博客一、文档编写目的昨天在群里看到一个刚学java的朋友碰到一个问题,他用文本编辑器写了一个java类,这大概就是所有java初学者刚开始都要经历的阶段吧,然后使用javac编译,在用java运行,出现了一个错误,在这里进行总结一下,希望对大家和我都有点帮助。二、场景还原java代码如下public class Byte { public static void main(String[] args) { byte x = 22; //x是十进制 by...https://blog.csdn.net/qq_36908872/article/details/124062276javac编译问题:使用了未经检查或不安全的操作_张某某啊哈的博客-CSDN博客使用了未经检查或不安全的操作在本人用editplus写java文件时碰到的问题。 代码import java.util.*;class collection{ public static void main(String[] args) { Collection c1=new ArrayList(25); c1.add(new String("one")); c1.add(new String("two"));.https://blog.csdn.net/qq_36908872/article/details/124062356

java编译通过,运行却提示找不到或无法加载主类的解决方案_张某某啊哈的博客-CSDN博客一、问题描述java(javac HelloWorld.java)编译通过,(java HelloWorld)运行却 提示找不到或无法加载主类 的一般多见过java初上手,使用命令行的方式运行java程序,一般使用IDE工具是不会遇见的。二、分析和解决既然javac编译已经通过,这说明变量 JAVA-HOME 已经配置的没有问题了。第一种可能就是:问题就出在Path变量对应的变量值上或者是新建用户变量classpath上有问题,你重新配置一下。Path对应的变量值是在原来的变量值前面加上%Javhttps://blog.csdn.net/qq_36908872/article/details/124062439

运行该程序时设置JVM的堆内存(heapsize)的极限值为10M(-Xmx10m)

如果直接执行这个程序的话,它会直到耗至我们机器上所有的内存才会报错,方便我们进行演示,运行的时候加上-Xmx10m。

运行之后等待一会,如果不想等待这么久的话,还可以将运行内存调整至5M

报错的结果

产生内存溢出的问题,现在我们该如何分析呢?

可以使用Heap Dump。

什么是Heap Dump呢?

一个Heap Dump是指在某个时刻对一个java进程所使用的内存情况的一次快照。也就是在某个时刻把Java进程的内存以某种格式持久化到了磁盘上。

如何生成Head Dump文件?

设置参数: —— -XX:+HeapDumpOnOutOfMemoryError

此参数是帮助生成dump文件,程序启动后直到抛出OOM异常。异常抛出后,在程序的classpath下生成以一个.hprof结尾的文件,如:java_pid4504.hprof,这就是我们需要的dump文件。

我们先看一下该目录,是没有.hprof文件的

加上这个参数我们在运行一次

抛出异常之后

再来看一下test目录

这是我们可以看到一件生成了.hprof文件,在实际生产环境中这个文件会非常大。
 

常用的一个分析器 Jprofiler 来分析文件

可以看见占用了很大的堆内存

查看Reference 选中要查看的了类

 定位到类后排查代码

当list数量太大时,就会导致OOM

工具下载地址  https://download.csdn.net/download/qq_36908872/85099750https://download.csdn.net/download/qq_36908872/85099750

扩展

生成Dump文件,JVM启动时添加参数:

#出现 OOME 时生成堆 dump:
-XX:+HeapDumpOnOutOfMemoryError
#生成堆文件地址:
-XX:HeapDumpPath=/home/xxx/logs/

linux springboot

nohup java -Xms2048m -Xmx2048m -XX:NewSize=384m -XX:MaxNewSize=450m -XX:PermSize=128m
 -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/darren/logs/ 
 -jar test.jar --spring.profiles.active=prod &

nohup java
-Xms2048m 指定堆内存初始化大小
-Xmx2048m 指定堆内存最大内存大小,
Xms设置和Xmx设置相同是为了避免频繁扩容和GC释放堆内存造成系统开销压力
-XX:NewSize=384m 新生代初始化内存的大小
-XX:MaxNewSize=450m 新生代可被分配的内存的最大上限(注意:该值需要小于-Xmx的值)
-XX:PermSize=128m 非堆区初始化内存分配大小
-XX:MaxPermSize=2048m 非堆区分配的内存的最大上限
-XX:+HeapDumpOnOutOfMemoryError 当JVM发生OOM时,自动生成DUMP文件
-XX:HeapDumpPath=/home/darren/logs/ 生成目录

nohup 英文全称 no hang up(不挂起),用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。
nohup 命令,在默认情况下(非重定向时),会输出一个名叫 nohup.out 的文件到当前目录下,如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值