JVM 参数 和基础原理验证

作者: zcwfeng | 来源:发表于2020-06-09 23:40 被阅读0次

官方文档
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html

一些重要概念的验证。jvm的参数太多了

OOM

-XX:MaxDirectMemorySize

/**
 * VM Args:-XX:MaxDirectMemorySize=100m
 * 堆外内存(直接内存溢出)
 */
public class DirectOom {
    public static void main(String[] args) {
        //直接分配128M的直接内存(100M)
        ByteBuffer bb = ByteBuffer.allocateDirect(128*1024*1204);
    }
}

-Xms30m -Xmx30m -XX:+PrintGCDetails (打印信息)

/**
 * VM Args:-Xms30m -Xmx30m -XX:+PrintGCDetails
 * 堆内存溢出(直接溢出)
 */
public class HeapOom {
   public static void main(String[] args)
   {

       String[] strings = new String[35*1000*1000];  //35m的数组(堆)
   }
}

-XX:+HeapDumpOnOutOfMemoryErro (GC调优---生产服务器推荐开启(默认是关闭的))

/**
 * VM Args:-Xms30m -Xmx30m -XX:+PrintGC    堆的大小30M
 * 造成一个堆内存溢出(分析下JVM的分代收集)
 * GC调优---生产服务器推荐开启(默认是关闭的)
 * -XX:+HeapDumpOnOutOfMemoryErro
 */
public class HeapOom2 {
   public static void main(String[] args)
   {
        //GC ROOTS
       List<Object> list = new LinkedList<>(); // list   当前虚拟机栈(局部变量表)中引用的对象  是1,不是走2
       int i =0;
       while(true){
           i++;
           if(i%10000==0) System.out.println("i="+i);
           list.add(new Object());
       }

   }
}

导入cglib-3.2.5.jar,asm-5.0.4.jar 我一般直接用gradle管理比较方便
-XX:MetaspaceSize=10M -XX:MaxMetaspaceSize=10M

/**
 * cglib动态生成
 * Enhancer中 setSuperClass和setCallback, 设置好了SuperClass后, 可以使用create制作代理对象了
 * 限制方法区的大小导致的内存溢出
 * VM Args: -XX:MetaspaceSize=10M -XX:MaxMetaspaceSize=10M
 * */
public class MethodAreaOutOfMemory {

    public static void main(String[] args) {
        while (true) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(MethodAreaOutOfMemory.TestObject.class);
            enhancer.setUseCache(false);
            enhancer.setCallback(new MethodInterceptor() {
                public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
                    return arg3.invokeSuper(arg0, arg2);
                }
            });
            enhancer.create();
        }
    }

    public static class TestObject {
        private double a = 34.53;
        private Integer b = 9999999;
    }
}

堆栈溢出 -Xss1m

/**
 * 栈溢出 -Xss1m
 */
public class StackOverFlow {

    public void king(){//一个栈帧--虚拟机栈运行
        king();//无穷的递归
    }
    public static void main(String[] args)throws Throwable {
        StackOverFlow javaStack = new StackOverFlow(); //new一个对象
        javaStack.king();
    }
}

JVM 运行底层基础逻辑 , 结合HSDB去查看

Object回收的JMM

/**
 *从底层深入理解运行时数据区
 * -Xms30m -Xmx30m -XX:+UseConcMarkSweepGC -XX:-UseCompressedOops
 * -Xss1m
 */

public class JVMObject {
    public final static String MAN_TYPE = "man"; // 常量
    public static String WOMAN_TYPE = "woman";  // 静态变量

    public static void  main(String[] args)throws Exception {//栈帧
        Teacher T1 = new Teacher();//堆中   T1 是局部变量
        T1.setName("Mark");
        T1.setSexType(MAN_TYPE);
        T1.setAge(36);
        for (int i=0;i<15;i++){//进行15次垃圾回收
            System.gc();//垃圾回收
        }
        Teacher T2 = new Teacher();
        T2.setName("King");
        T2.setSexType(MAN_TYPE);
        T2.setAge(18);
        Thread.sleep(Integer.MAX_VALUE);//线程休眠很久很久
    }
}

class Teacher{
    String name;
    String sexType;
    int age;//堆

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public String getSexType() {
        return sexType;
    }
    public void setSexType(String sexType) {
        this.sexType = sexType;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

栈帧之间数据的共享

/**
 * 栈帧之间数据的共享
 */
public class JVMStack {

    public int work(int x) throws Exception{
        int z =(x+5)*10;//局部变量表有
        Thread.sleep(Integer.MAX_VALUE);
        return  z;
    }
    public static void main(String[] args)throws Exception {
        JVMStack jvmStack = new JVMStack();
        jvmStack.work(10);//10  放入main栈帧操作数栈
    }
}

虚拟机优化手段-方法内联
实际上就是减少方法,原理就是减少方法进出虚拟机栈的消耗

/**
 * 方法内联
 */
public class MethodDeal {

    public static void main(String[] args) {
       // max(1,2);//调用max方法:  虚拟机栈 --入栈(max 栈帧)
        boolean i1 = 1>2;
    }
    public static boolean max(int a,int b){//方法的执行入栈帧。
        return a>b;
    }
}

打断点查看,或者javap -c 查看字节码

/**
 * 栈帧执行对内存区域的影响
 */
public class Person {

    public  int work()throws Exception{//运行过程中 打包一个栈帧
        int x =1;//x是一个局部变量
        int y =2;
        int z =(x+y)*10;
        return  z;
    }
    public static void main(String[] args) throws Exception{
        Person person = new Person();//person 一个引用, new Person()对象
        person.work();//执行完了,出栈
        person.hashCode();
        int i =12;
    }
}

既然都看到了最后,那么送你一份礼物:一个排序算法非常好的图解文章
https://xiaozhuanlan.com/

再次可以搜索关注公众号:

靖驿站

或者

  IT-TIANYA

相关文章

网友评论

    本文标题:JVM 参数 和基础原理验证

    本文链接:https://www.haomeiwen.com/subject/ygsytktx.html