优秀的编程知识分享平台

网站首页 > 技术文章 正文

内存溢出一般发生在哪个区?永久代会不会导致内存溢出?

nanyue 2024-10-12 05:46:50 技术文章 15 ℃

【死记硬背】

一般会发生在:堆溢出、永久代/元空间溢出、方法栈溢出

【答案解析】

堆溢出

这种场景最为常见,报错信息:

java.lang.OutOfMemoryError:Java heap space

原因:

1、代码中可能存在大对象分配

2、可能存在内存泄露,导致在多次GC之后,还是无法找到一块足够大的内存容纳当前对象。

解决方法:

1、检查是否存在大对象的分配,最有可能的是大数组分配

2、通过jmap命令,把堆内存dump下来,使用mat工具分析一下,检查是否存在内存泄露的问题

3、如果没有找到明显的内存泄露,使用 -Xmx 加大堆内存

4、还有一点容易被忽略,检查是否有大量的自定义的 Finalizable 对象,也有可能是框架内部提供的,考虑其存在的必要性

永久代/元空间溢出

java.lang.OutOfMemoryError:PermGen spacejava.java.OutOfMemoryError:Metaspace

原因:

永久代是 HotSot 虚拟机对方法区的具体实现,存放了被虚拟机加载的类信息、常量、静态变量、JIT编译后的代码等。JDK8后,元空间替换了永久代,元空间使用的是本地内存,还有其它细节变化:字符串常量由永久代转移到堆中和永久代相关的JVM参数已移除可能原因有如下几种:

1、在Java7之前,频繁的错误使用String.intern()方法

2、运行期间生成了大量的代理类,导致方法区被撑爆,无法卸载

3、应用长时间运行,没有重启没有重启 JVM 进程一般发生在调试时

解决方法:

因为该OOM原因比较简单,解决方法有如下几种:

1、检查是否永久代空间或者元空间设置的过小

2、检查代码中是否存在大量的反射操作

3、dump之后通过mat检查是否存在大量由于反射生成的代理类

4、放大招,重启JVM

方法栈溢出

java.lang.OutOfMemoryError: unable to create new native Thread

原因:

出现这种异常,基本上都是创建的了大量的线程导致的,以前碰到过一次,通过jstack出来一共8000多个线程。

解决方法:

1、通过 -Xss 降低的每个线程栈大小的容量

2、线程总数也受到系统空闲内存和操作系统的限制,检查是否该系统下有此限制:/proc/sys/kernel/pid_max/proc/sys/kernel/thread-maxmaxuserprocess(ulimit -u)/proc/sys/vm/maxmapcount

【温馨提示】

点赞+收藏文章,关注我并私信回复【面试题解析】,即可100%免费领取楼主的所有面试题资料!

最近发表
标签列表