/** * VM Args:-Xss160k */public class Test {private void dontStop() {while(true) { } }public void stackLeakByThread() {while (true) { Thread thread = new Thread(new Runnable() {@Overridepublic void run() { dontStop(); } }); thread.start(); } }public static void main(String[] args) { Test oom = new Test(); oom.stackLeakByThread(); }}运行以上代码会抛出「java.lang.OutOfMemoryError:unabletocreatenewnativethread」的异常,原因不难理解,操作系统给每个进程分配的内存是有限制的,比如32位的Windows限制为2G,虚拟机提供了参数来控制Java堆和方法的这两部内存的最大值,剩余的内存为「2G-Xmx(最大堆容量)=线程数*每个线程分配的虚拟机栈(-Xss)+本地方法栈」(程序计数器消耗内存很少,可忽略),每个线程都会被分配对应的虚拟机栈大小,所以总可创建的线程数肯定是固定的,像以上代码这样不断地创建线程当然会造成最终无法分配,不过这也给我们提供了一个新思路,如果是因为建立过多的线程导致的内存溢出,而我们又想多创建线程,可以通过减少最大堆(-Xms)和减少虚拟机栈大小(-Xss)来实现。2、堆溢出(java.lang.OutOfMemoryError:Javaheapspace)主要原因有两点
1.大对象的分配,最有可能的是大数组分配
示例如下:/*** VM Args:-Xmx12m */class OOM {static final int SIZE=2*1024*1024;public static void main(String[] a) {int[] i = new int[SIZE]; }}我们指定了堆大小为12M,执行「java-Xmx12mOOM」命令就发生了OOM异常,如果指定13M则以上程序就能正常执行,所以对于由于大对象分配导致的堆溢出这种OOM,我们一般采用增大堆内存的方式来解决