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