java堆用于存储对象实例,只要不断建立对象,而且保证GC Roots到对象之间的可达路径来避免垃圾回收机制清理这些对象,那么当对象的达到堆的容量最大值滞后就会产生outofmemoryerror;java
经过参数:-Xms20m 最小堆大小; -Xmx20m 最大堆大小; -XX:+HeapDumpOnOutOfMemoryError 虚拟机在内存溢出异常时Dump出当前的内存堆转储快照windows
具体配置:ide
-verbose:gc -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:SurvivorRatio=8
代码:测试
1 package javaTest; 2 3 import java.io.Serializable; 4 import java.util.LinkedList; 5 import java.util.List; 6 7 public class Portal { 8 9 /** 10 * vm args : -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError 11 * @param args 12 */ 13 public static void main(String[] args) { 14 System.out.println("test heap memory dump"); 15 16 17 List<HeapOOM> lists = new LinkedList<HeapOOM>(); 18 19 while(true){ 20 lists.add(new HeapOOM()); 21 } 22 23 24 25 } 26 27 public static class HeapOOM implements Serializable{ 28 29 /** 30 * 31 */ 32 private static final long serialVersionUID = -7562967142125991489L; 33 34 private int count; 35 36 public int getCount() { 37 return count; 38 } 39 40 public void setCount(int count) { 41 this.count = count; 42 } 43 44 45 } 46 47 }
异常:this
注意:必定要辨别是内存泄露(memory Leak)仍是内存溢出(memory Overflow)spa
若是线程请求的栈深度大于虚拟机所容许的最大深度,将抛出StackOverFlowError异常;线程
若是虚拟机的扩展栈没法申请到足够的内存空间,则抛出OutOfMemoryError异常;3d
参数:-Xoss 设置本地方法栈大小;-Xss 设置虚拟机房发展大小code
具体设置:对象
-Xss128k
代码:
1 package javaTest; 2 3 public class StackOverFlowTest { 4 5 /** 6 * vm args : -Xss128K 7 * @param args 8 */ 9 public static void main(String[] args){ 10 11 OverFlowStackClass model = new OverFlowStackClass(); 12 13 try{ 14 model.stackLeak(); 15 }catch(Throwable ex){ 16 System.out.println("最大深度:"+String.valueOf(model.stackLength)); 17 throw ex; 18 } 19 20 21 22 23 24 25 } 26 27 static class OverFlowStackClass{ 28 public int stackLength=1; 29 30 public void stackLeak(){ 31 stackLength++; 32 stackLeak(); 33 } 34 } 35 36 37 38 }
异常:
若是是建立过多的线程致使内存溢出,在不减小线程数量或者更换64bit虚拟机的状况下,就只能经过减小最大堆和减小虚拟机栈容量来换取更多的线程,若是没有这方便的处理经验,这种经过增长线程挤占java虚拟机栈的方式来验证java栈的内存溢出(outofmemoryerror)的场景是很难想到的;
本人电脑是windows这里对于这种状况就不作演示了,代码实现其实就是疯狂的建立新的线程来实现。java栈的内存溢出;
String.intern();是一个Native方法,它的做用是 若是字符串常量池中已经包含一个等于此String对象的字符串,则返回字符串常量池中的这个字符串;不然建立一个新的对象,该对象添加到常量池中,最后返回此字符串的引用。
参数:-XX:PermSize -XX:MaxPermSize
具体参数:
-XX:PermSize=10M -XX:MaxPermSize=10M
代码:
1 package javaTest; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 public class MethodOutOfMemoryError { 7 8 /** 9 * vm args: -XX:PermSize=10M -XX:MaxPermSize=10M 10 * @param args 11 */ 12 public static void main(String[] args){ 13 14 List<String> lists = new ArrayList<String>(); 15 16 int i=0; 17 while(true){ 18 lists.add(String.valueOf(i++).intern()); 19 } 20 21 } 22 23 }
异常:
1.7+以上版本不会出现异常了,能够经过:-verbose:gc查看GC的回收过程;
参数:-XX:MaxDirectMemorySize 制定可使用的机器内存的大小
具体运行参数:
-Xmx10m -XX:MaxDirectMemorySize=10m
代码:
1 package javaTest; 2 3 import java.lang.annotation.Annotation; 4 import java.lang.reflect.Field; 5 6 import sun.misc.Unsafe; 7 8 public class DirectMemoryTest { 9 10 private static final int _1MB = 1024*1024; 11 12 /** 13 * vm agrs: -Xmx10m -XX:MaxDirectMemorySize=10m 14 * @param args 15 * @throws IllegalAccessException 16 * @throws IllegalArgumentException 17 */ 18 public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException{ 19 20 System.out.println(_1MB); 21 22 Field unsafeField = Unsafe.class.getDeclaredFields()[0]; 23 unsafeField.setAccessible(true); 24 Unsafe unsafe = (Unsafe)unsafeField.get(null); 25 while(true){ 26 unsafe.allocateMemory(_1MB); 27 } 28 29 30 31 32 } 33 }
异常:
虽然java有垃圾回收机制,可是内存溢出对咱们来讲也是屡见不鲜,因此要明白什么状况下致使内存溢出,从而尽可能避免内存溢出的发生;
若是出现内存异常根据堆栈信息能够快速排查是什么缘由;