那些场景产生OOM?怎么解决?

1、堆内存溢出

堆内存用来存储对象实例,只要不停的创建对象,并且保证GC Roots和对象之间有可达路径避免垃圾回收,那么在对象数量超过最大堆的大小限制后很快就能出现这个异常。

2、方法区和元空间溢出

方法区和堆一样,是线程共享的区域,包含class文件信息、运行时常量池、常量池。不一定非要是class文件中的常量池中的内容才能进入运行时常量池,运行期间也可以将新的常量放入池中,比如String的intern()方法。

intern()本身是一个native方法,它的作用是:如果字符串常量池中已经包含一个等 于此String对象的字符串,则返回代表池中这个字符串的String对象;否则,将此String对象包含的字符串添加到常量池中,并且返回String对象的引用。

而在1.7版本之后,字符串常量池已经转移到堆区,所以会报出堆内存溢出的错误,如果1.7之前版本的话会看见PermGen space的报错。

3、直接内存溢出

4、栈内存溢出

在java虚拟机规范中,对虚拟机栈定义了两种异常:

  • 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverFlowError
  • 如果虚拟机可以动态扩展,并且扩展时无法申请到足够的内存,抛出OutOfMemoryError。

测试发现,单线程下无论怎么设置参数都是StackOverflow异常。
把代码修改为多线程,调整-Xss2m,因为为每个线程分配的内存越大,栈空间可容纳的线程数量越少,越容易产生内存溢出。反之,如果内存不够的情况,可以调小该参数来达到支撑更多线程的目的。

猜你喜欢

转载自blog.csdn.net/qq_37935909/article/details/108816068
今日推荐