Java虚拟机之JVM整理学习笔记(二)

上篇文章,散仙整理了关于JVM的运行时的数据区以及各个区域,本篇我们就来看下各个区域发生异常代码的实战代码,以便于大家更容易在实际应用找到感觉。


1,JAVA堆溢出代码,需要设置JVM参数



Java代码   收藏代码
  1. package com.test.jvm;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6.   
  7. /** 
  8.  *  
  9.  * 堆异常 
  10.  *  
  11.  * VM参数 
  12.  * -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError 
  13.  * -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError 生成dump文件 
  14.  *-XX:+PrintGCDetails //打印GC日志 
  15.  *  
  16.  * **/  
  17. public class HeapOOM {  
  18.       
  19.       
  20.     static class OOMObject{  
  21.           
  22.           
  23.     }  
  24.       
  25.       
  26.     public static void main(String[] args) {  
  27.           
  28.           
  29.         List<OOMObject> oom=new ArrayList<HeapOOM.OOMObject>();  
  30.         while(true){  
  31.             oom.add(new OOMObject());  
  32.         }  
  33.           
  34.           
  35.     }  
  36.   
  37. }  

 

Java代码   收藏代码
  1. [GC [PSYoungGen: 5066K->817K(5952K)] 5066K->3649K(19648K), 0.0086059 secs] [Times: user=0.03 sys=0.00, real=0.02 secs]   
  2. [GC [PSYoungGen: 5937K->816K(5952K)] 8769K->7014K(19648K), 0.0071084 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]   
  3. [GC [PSYoungGen: 5936K->832K(5952K)] 12134K->12141K(19648K), 0.0091434 secs] [Times: user=0.03 sys=0.00, real=0.01 secs]   
  4. [Full GC [PSYoungGen: 832K->0K(5952K)] [ParOldGen: 11309K->10673K(13696K)] 12141K->10673K(19648K) [PSPermGen: 2492K->2490K(21248K)], 0.1771161 secs] [Times: user=0.25 sys=0.00, real=0.18 secs]   
  5. [Full GC [PSYoungGen: 5120K->0K(5952K)] [ParOldGen: 10673K->13682K(13696K)] 15793K->13682K(19648K) [PSPermGen: 2490K->2490K(21248K)], 0.0549867 secs] [Times: user=0.17 sys=0.00, real=0.06 secs]   
  6. [Full GC [PSYoungGen: 2648K->2599K(5952K)] [ParOldGen: 13682K->13694K(13696K)] 16331K->16293K(19648K) [PSPermGen: 2490K->2490K(21248K)], 0.1501946 secs] [Times: user=0.28 sys=0.00, real=0.15 secs]   
  7. [Full GC [PSYoungGen: 2599K->2595K(5952K)] [ParOldGen: 13694K->13692K(13696K)] 16293K->16287K(19648K) [PSPermGen: 2490K->2490K(21248K)], 0.0715712 secs] [Times: user=0.19 sys=0.00, real=0.07 secs]   
  8. java.lang.OutOfMemoryError: Java heap space  
  9. Dumping heap to java_pid7016.hprof ...  
  10. Heap dump file created [27848402 bytes in 0.106 secs]  
  11. Exception in thread "main" java.lang.OutOfMemoryError: Java heap space  
  12.     at java.util.Arrays.copyOf(Arrays.java:2245)  
  13.     at java.util.Arrays.copyOf(Arrays.java:2219)  
  14.     at java.util.ArrayList.grow(ArrayList.java:213)  
  15.     at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:187)  
  16.     at java.util.ArrayList.add(ArrayList.java:411)  
  17.     at com.test.jvm.HeapOOM.main(HeapOOM.java:30)  
  18. Heap  
  19.  PSYoungGen      total 5952K, used 2771K [0x00000000ff9600000x00000000000000000x0000000000000000)  
  20.   eden space 5120K, 54% used [0x00000000ff960000,0x00000000ffc14d28,0x00000000ffe60000)  
  21.   from space 832K, 0% used [0x00000000ffe60000,0x00000000ffe60000,0x00000000fff30000)  
  22.   to   space 832K, 0% used [0x00000000fff30000,0x00000000fff30000,0x0000000000000000)  
  23.  ParOldGen       total 13696K, used 13692K [0x00000000fec000000x00000000ff9600000x00000000ff960000)  
  24.   object space 13696K, 99% used [0x00000000fec00000,0x00000000ff95f148,0x00000000ff960000)  
  25.  PSPermGen       total 21248K, used 2523K [0x00000000f9a000000x00000000faec00000x00000000fec00000)  
  26.   object space 21248K, 11% used [0x00000000f9a00000,0x00000000f9c76e98,0x00000000faec0000)  



生成的dump文件,可以使用Eclipse Memory Analyzer进行分析查看,注意下载的不是eclipse插件,直接可与双击运行的。下载地址



2,虚拟机栈和本地方法栈溢出

Java代码   收藏代码
  1. package com.test.jvm;  
  2.   
  3.   
  4. /**  
  5.  * 栈异常  
  6.  * 如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError  
  7.  * 如果虚拟机在扩展栈时无法申请到足够的内存空间,将抛出OutOfMemoryError  
  8.  * VM Args:-Xss128k  
  9.  */  
  10. public class VMStacSOF {  
  11.       
  12.     public   int count=1;  
  13.       
  14.       void add(){  
  15.             count++;  
  16.         add();  
  17.       
  18.           
  19.     }  
  20.       
  21.     public static void main(String[] args)throws Throwable {  
  22.         VMStacSOF vss=new VMStacSOF();  
  23.          try{  
  24.       
  25.         vss.add();  
  26.           
  27.          }catch(Throwable e){  
  28.             System.out.println("stack的length: "+vss.count);  
  29.              throw e;  
  30.          }  
  31.     }  
  32.   
  33. }  

 

Java代码   收藏代码
  1. Exception in thread "main" stack的length: 997  
  2. java.lang.StackOverflowError  
  3.     at com.test.jvm.VMStacSOF.add(VMStacSOF.java:15)  
  4.     at com.test.jvm.VMStacSOF.add(VMStacSOF.java:16)  
  5.     at com.test.jvm.VMStacSOF.add(VMStacSOF.java:16)  
  6.     at com.test.jvm.VMStacSOF.add(VMStacSOF.java:16)  
  7.     at com.test.jvm.VMStacSOF.add(VMStacSOF.java:16)  
  8.     at com.test.jvm.VMStacSOF.add(VMStacSOF.java:16)  




3,方法区和运行时常量池溢出

Java代码   收藏代码
  1. package com.test.jvm;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. /*** 
  7.  *  
  8.  *  
  9.  * 方法区异常 
  10.  * -XX:PermSize=3M -XX:MaxPermSize=3M 
  11.  *  
  12.  * */  
  13. public class MethodAreaOOM {  
  14.       
  15.       
  16.     public static void main(String[] args) {  
  17.           
  18.         //保持常量引用,避免FULL GC  
  19.         List<String> list=new ArrayList<String>();  
  20.           
  21.         int i=0;  
  22.         while(true){  
  23.             list.add(String.valueOf(i+"fdfd的说法弄得你辅导费多方面的发叫电缆附件的封疆大吏防静电发来的发动静分离定界符多久奋斗飞地方的飞").intern());  
  24.         //System.out.println(i);  
  25.             i++;  
  26.         }  
  27.     }  
  28.   
  29. }  


Java代码   收藏代码
  1. Exception in thread "Reference Handler" Error occurred during initialization of VM  
  2. java.lang.OutOfMemoryError: PermGen space  
  3.     at sun.misc.Launcher$ExtClassLoader.getExtClassLoader(Launcher.java:141)  
  4.     at sun.misc.Launcher.<init>(Launcher.java:71)  
  5.     at sun.misc.Launcher.<clinit>(Launcher.java:57)  
  6.     at java.lang.ClassLoader.initSystemClassLoader(ClassLoader.java:1486)  
  7.     at java.lang.ClassLoader.getSystemClassLoader(ClassLoader.java:1468)  
  8.   
  9.   
  10. Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Reference Handler"  




4,直接内存区异常:

Java代码   收藏代码
  1. package com.test.jvm;  
  2.   
  3. import java.lang.reflect.Field;  
  4.   
  5. import sun.misc.Unsafe;  
  6.   
  7.   
  8. /** 
  9.  *  
  10.  * 直接内存溢出 
  11.  * -Xmx20M -XX:MaxDirectMemorySize=10M  
  12.  * 切换JDK1.6才有Unsafe这个类,在JDK1.7中不存在此类 
  13.  *  
  14.  * */  
  15. public class DirectMemoryOOM {  
  16.       
  17.      private static final int _1MB = 1024 * 1024;    
  18.         
  19.         public static void main(String[] args) throws Exception {    
  20.                 
  21.             Field unsafeField = Unsafe.class.getDeclaredFields()[0];    
  22.             unsafeField.setAccessible(true);    
  23.             Unsafe unsafe = (Unsafe) unsafeField.get(null);    
  24.             while (true) {    
  25.                 unsafe.allocateMemory(_1MB);    
  26.             }    
  27.         }    
  28.   
  29. }  

 

Java代码   收藏代码
  1. Exception in thread "main" java.lang.OutOfMemoryError  
  2.     at sun.misc.Unsafe.allocateMemory(Native Method)  
  3.     at com.test.jvm.DirectMemoryOOM.main(DirectMemoryOOM.java:24)  



5,String.intern()的使用,看下面例子

Java代码   收藏代码
  1. package com.test.jvm;  
  2.   
  3. /*** 
  4.  *  
  5.  * String.intern()方法 
  6.  * 测试 
  7.  * intern()方法,会先从常量池,查找是否在方法区以及存在此对象的 
  8.  * 引用,如果存在,就返回,如果不存在,就创建一个新的再放回去 
  9.  *  
  10.  * **/  
  11. public class TestIntern {  
  12.       
  13.     public static void main(String[] args) {  
  14.           
  15.           
  16.           
  17.         String str1=new StringBuilder("我们").append("在这里").toString();  
  18.         //这里打印true是因为,常量池不存在,此对象,故把此对象添加进去,然后再取出来,做比较,由于引用地址一样,故为true  
  19.         System.out.println(str1.intern()==str1);  
  20.         System.out.println("===================================================");  
  21.         String str2=new StringBuilder("lon").append("g").toString();  
  22.         //这里会输入false,是因为常量池里面已经存在,long ,int,java等字样,与刚创建的实例引用地址不一样,故为false  
  23.         System.out.println(str2.intern()==str2);  
  24.           
  25.           
  26.           
  27.     }  
  28.   
  29. }  


Java代码   收藏代码
  1. true  
  2. ===================================================  
  3. false  

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值