当前位置: 首页 > 图灵资讯 > java面试题> 金三银四精选面试题-内存溢出一般发生在哪个区?永久代会不会导致内存溢出?

金三银四精选面试题-内存溢出一般发生在哪个区?永久代会不会导致内存溢出?

来源:图灵教育
时间:2023-11-16 09:45:37
 

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

堆溢出

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

java.lang.OutOfMemoryError: Java heap space

原因

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

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

解决方法

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

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

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

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

永久代/元空间溢出

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

原因

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

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

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

3、应用长时间运行,没有重启没有重启 JVM 进程一般发生在调试时,如下面 tomcat 官网的一个 FAQ:

Why does the memory usage increase when I redeploy a web application? That is because your web application has a memory leak. A common issue are “PermGen” memory leaks. They happen because the Classloader (and the Class objects it loaded) cannot be recycled unless some requirements are met (). They are stored in the permanent heap generation by the JVM, and when you redeploy a new class loader is created, which loads another copy of all these classes. This can cause OufOfMemoryErrors eventually. ( *) The requirement is that all classes loaded by this classloader should be able to be gc’ed at the same time.

解决方法

因为该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