java面试:内存溢出

问题描述:

如果在程序运行时,遇到内存溢出,该如何着手解决?

思路分析

内存溢出是指java程序运行时,某一块内存空间耗尽,导致OutOfMemory错误(简称OOM)。

那么根据JVM的基本结构图,我们可以看到运行时数据区主要包括方法区,堆,直接内存,还有java虚拟机栈,当对应的内存空间耗尽的时候,都会出现OOM错误。图片取自https://www.jianshu.com/p/8a58d8335270

内存溢出原因

经过分析,通常情况下,内存溢出主要有五种情况
1.堆溢出:
堆内存主要用于保存java创建的对象,当java代码中创建了大量对象,而这些对象都持有强引用,导致无法回收,当对象大小之和大于堆空间大小时,就会产生内存溢出。
2.方法区溢出:
方法区主要保存了类信息,如果java程序不停地创建新的类,就有可能导致方法区溢出。同时,方法区中还包含了运行时常量池,如果我们代码中不停地动态生成字符串,那么也有可能导致方法区溢出。
3.直接内存溢出:
java的NIO中支持直接内存的使用,也就是通过java代码,向系统申请获取一块堆外的内存空间。如果频繁地申请直接内存,就有可能触发内存溢出。(如果使用jdk64位虚拟机,一般不会出现这种问题,因为64位系统没有对程序可用最大内存做限制,而32位系统中,内存寻址空间为4G,其中用户空间2G,系统空间2G,当java进程所有内存之和大于2G时,就会出现OOM
4.线程过多:
每一个线程的开启都会占用系统内存,因此,当线程数量过多时,也有可能导致OOM。它的情况与直接内存比较相似。
5.垃圾回收效率低:
java除了内存占用,还有内存回收,是通过GC来进行的,可以想象,如果申请内存的速度超过内存回收的速度,那么迟早都会出现OOM。

测试案例编写思路

1.暴力溢出,直接创建大量对象来耗尽分配的内存空间

//代码执行时可以添加参数-Xmx分配一个较小的堆最大空间,以便观测
public class SimpleHeapOOM {
		pubic static void main(String args[]){
			ArrayList<byte[]> list =new ArrayList<byte[]>();
			for(int i=0;i<1024;i++){
			      list.add(new byte[1024*1024]);
			}
		}
}

2.内存泄露。具体可以参看这篇文章Java应用内存泄露排查

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值