Java虚拟机(jdk1.8) 学习笔记 (模拟栈溢出)

1、由于HotSpot虚拟机中并不区分虚拟机栈和本地方法栈,对于-Xoss(设置虚拟机栈大小)虽然存在,但是实际上没有任何效果,栈容量只能由-Xss参数来设定。

2、导致栈异常的两种情况:

  1. 如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverFlowError异常
  2. 如果虚拟机的栈内存允许动态扩展,关于扩展栈容量无法申请到足够的内存时,将抛出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);
        }
    }

}
经验分享 程序员 微信小程序 职场和发展