Java虚拟机(jdk1.8) 学习笔记 (模拟栈溢出)
1、由于HotSpot虚拟机中并不区分虚拟机栈和本地方法栈,对于-Xoss(设置虚拟机栈大小)虽然存在,但是实际上没有任何效果,栈容量只能由-Xss参数来设定。
2、导致栈异常的两种情况:
- 如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverFlowError异常
- 如果虚拟机的栈内存允许动态扩展,关于扩展栈容量无法申请到足够的内存时,将抛出OutOfMemoryError异常
HotSpot虚拟机中的选择是不支持栈的动态扩展,除非在创建线程申请时就无法获得足够内存出现OutOfMemoryError异常,否则在线程运行时不会因为扩展而导致内存溢出的。
栈容量配置:-Xss128k
1、模拟栈溢出(方法调用深度过深,使用递归循环模拟调用):
代码:
package com.wzz.jvm; /** * @author wzz * @description: 栈溢出测试(栈调用长度测试) * @since JDK 1.8 */ public class JvmTest2 { private int stackLength = 1 ; public void stackLeak(){ stackLength++; stackLeak(); } public static void main(String[] args){ JvmTest2 jvmTest2 = new JvmTest2(); try{ jvmTest2.stackLeak(); }catch (StackOverflowError e){ System.out.println("stack length:"+jvmTest2.stackLength); } } }
2、模拟栈溢出(栈帧过大导致的栈溢出)
代码:
package com.wzz.jvm; /** * @author wzz * @description: 栈溢出测试(栈帧过大测试) * @since JDK 1.8 */ public class JvmTest3 { private static int stackLengh = 0; public void stackLeak(){ long wzz1,wzz2,wzz3,wzz4,wzz5,wzz6, awzz1,bwzz21,cwzz31,dwzz42,ewzz51,fwzz6a, awzz2,bwzz22,cwzz32,dwzz43,ewzz52,fwzz6b, awzz3,bwzz23,cwzz33,dwzz45,ewzz53,fwzz6c, awzz4,bwzz24,cwzz34,dwzz421,ewzz54,fwzz6aq, awzz5,bwzz25,cwzz35,dwzz415,ewzz55,fwzz6ef, awzz6,bwzz26,cwzz36,dwzz412,ewzz56,fwzz6wrg, awzz7,bwzz27,cwzz37,dwzz442,ewzz57,fwzz6www, awzz8,bwzz28,cwzz38,dwzz452,ewzz58,fwzz6wwww, awzz9,bwzz29,cwzz39,dwzz451,ewzz59,fwzz6eee, awzz10,bwzz211,cwzz311,dwzz4122,ewzz52a,fwzz6w, awzz11,bwzz221,cwzz312,dwzz443,ewzz5rb,fwzz62, awzz12,bwzz231,cwzz313,dwzz4112,ewzz5ww,fwzz6e, awzz13,bwzz241,cwzz314,dwzz413,ewzz5eww,fwzz6s, awzz14,bwzz251,cwzz315,dwzz4421,ewzz5f,fwzz64, awzz15,bwzz261,cwzz316,dwzz4133,ewzz5ty,fwzz627, awzz16,bwzz271,cwzz332,dwzz4411,ewzz5h,fwzz61, awzz17,bwzz281,cwzz322,dwzz4511,ewzz5g,fwzz65; stackLengh ++; stackLeak(); wzz1=wzz2=wzz3=wzz4=wzz5=wzz6= awzz1=bwzz21=cwzz31=dwzz42=ewzz51=fwzz6a =awzz2=bwzz22=cwzz32=dwzz43=ewzz52=fwzz6b =awzz3=bwzz23=cwzz33=dwzz45=ewzz53=fwzz6c =awzz4=bwzz24=cwzz34=dwzz421=ewzz54=fwzz6aq =awzz5=bwzz25=cwzz35=dwzz415=ewzz55=fwzz6ef =awzz6=bwzz26=cwzz36=dwzz412=ewzz56=fwzz6wrg =awzz7=bwzz27=cwzz37=dwzz442=ewzz57=fwzz6www =awzz8=bwzz28=cwzz38=dwzz452=ewzz58=fwzz6wwww =awzz9=bwzz29=cwzz39=dwzz451=ewzz59=fwzz6eee =awzz10=bwzz211=cwzz311=dwzz4122=ewzz52a=fwzz6w =awzz11=bwzz221=cwzz312=dwzz443=ewzz5rb=fwzz62 =awzz12=bwzz231=cwzz313=dwzz4112=ewzz5ww=fwzz6e =awzz13=bwzz241=cwzz314=dwzz413=ewzz5eww=fwzz6s =awzz14=bwzz251=cwzz315=dwzz4421=ewzz5f=fwzz64 =awzz15=bwzz261=cwzz316=dwzz4133=ewzz5ty=fwzz627 =awzz16=bwzz271=cwzz332=dwzz4411=ewzz5h=fwzz61 =awzz17=bwzz281=cwzz322=dwzz4511=ewzz5g=fwzz65 = 0; } public static void main(String[] args) { JvmTest3 jvmTest3 = new JvmTest3(); try { jvmTest3.stackLeak(); }catch (StackOverflowError e){ System.out.println("stack length:"+stackLengh); } } }
上一篇:
通过多线程提高代码的执行效率例子