1:栈溢出java
这个简单理解就是方法运行期间须要分配内存,这类的内存就称之为栈。这类的溢出通常发生在方法的栈太长了,超出了最大深度,或者是超出了内存的。就会爆栈溢出。java 的异常对象为 StackOverFlowError。异步
上代码:如何模拟栈溢出来理解这个,简单的及时写一个不会跳出的递归。code
//若是不当心进入了这样的一个方法,毫无疑问他就会爆出 栈溢出,这个方法栈愈来愈长,会逐渐从虚拟机中分配新的内存。也不退出 //就会有栈溢出。 public void static enter(int number){ number++; enter(number) }
这是一个极端的例子,来简单的描述栈溢出发生的一个场景,现实中估计没人会在生产环境中写出这么一个代码出来,就是一个思路。若是发生了 stackoverflowError的话,能够顺着这个思路去分析问题。对象
2:堆泄露递归
堆简单说就是你生成出来的一系列的对象,何时会发生堆泄露呢,若是这堆对象一直存在,而且不能被垃圾回收,多到虚拟机没法为对象分配新的内存空间的时候,他就要爆堆泄露了。内存
public class HeapOMM{ public HeapOMM{ } public static void main(String args[]){ // 无止境的new 对象出来,而且也得不到回收,当内存再也不有空间尅使用的时候,虚拟机就要爆OMM了 while(true){ List<HeapOMM> list = new ArrayList<HeapOMM>(); list.add(new HeapOMM); } } }
也是一个思路。用于定位OMM发生的根本缘由。字符串
3:方法区和运行常量池的溢出虚拟机
这种状况不多,实在看书的时候发现的一种,在工做中尚未遇到过方法区的溢出。String的intern()方法,在字符串常量池中若是已经包含了一个String对象,则会直接返回池中的对象,若是没有的话,则会new一个放到常亮池中,若是一直new 不一样的String对象出来,常量池就会一直增长,当不知足虚拟机内存分配的时候也会爆溢出错误,可是这种我尚未在现实中遇到过。举个例子,记录一下吧。class
import java.util.ArrayList; import java.util.List; public class Strings { public static void main(String[] args) { List<String> list = new ArrayList<String>(); int i =1; while(true){ list.add(String.valueOf(i++).intern()); } } }
4:内存直接溢出import
这个不是虚拟机能把控的了,是发生在真实内存中的问题。有一个思路,就是看看代码中看有没有使用到NIO的地方。NIO使用的是异步IO,在里面涉及到直接操做外部内存的操做。能够看看这方面有没有什么问题。