• jvm2


     垃圾回收器的实现:

    1.让用户都暂停,不再产生垃圾,就去收集垃圾。新生代用复制算法清理垃圾,老生代用标记整理算法搜集垃圾。

     

    优秀的算法:服务端默认是CMS收集器。

    %.1.jvm案例演示
    内存:
        Jconsole的内存标签相当于可视化的jstat命令,用于监视收集器管理的虚拟机内存(java堆和永久代)的变化趋势。
        我们通过下面的一段代码体验一下它的监视功能。运行时设置的虚拟机参数为:-Xms100m -Xmx100m -XX:+UseSerialGC,这段代码的作用是以64kb/50毫秒的速度往java堆内存中填充数据。
    public class TestMemory {
        static class OOMObject {
            public byte[] placeholder = new byte[64 * 1024];
        }
    
        public static void fillHeap(int num) throws Exception {
            ArrayList<OOMObject> list = new ArrayList<OOMObject>();
            for (int i = 0; i < num; i++) {
                Thread.sleep(50);
                list.add(new OOMObject());
            }
            System.gc();
        }
    
        public static void main(String[] args) throws Exception {
            fillHeap(1000);
            Thread.sleep(500000);
        }
    }

    从图中可以看出,运行轨迹成曲线增长,循环1000次后,虽然整个新生代Eden和Survivor区都基本上被清空了,但是老年代仍然保持峰值状态,这说明,填充的数据在GC后仍然存活,因为list的作用域没有结束。如果把System.gc();移到fillHeap(1000);后,就可以全部回收掉。
    线程:
    jconsole线程标签相当于可视化了jstack命令,遇到线程停顿时,可以使用这个也签进行监控分析。线程长时间停顿的主要原因有:等待外部资源(数据库连接等),死循环、锁等待。下面的代码将演示这几种情况:
    package cn.java.jvm;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class TestThread {
        /**
         * 死循环演示
         * 
         * @param args
         */
        public static void createBusyThread() {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("createBusyThread");
                    while (true)
                        ;
                }
            }, "testBusyThread");
            thread.start();
        }
    
        /**
         * 线程锁等待
         * 
         * @param args
         */
        public static void createLockThread(final Object lock) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("createLockThread");
                    synchronized (lock) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
    
                }
            }, "testLockThread");
            thread.start();
        }
    
        public static void main(String[] args) throws Exception {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            br.readLine();
            createBusyThread();
            br.readLine();
            Object object = new Object();
            createLockThread(object);
        }
    }
    main线程:追踪到需要键盘录入
    testBusyThread线程:线程阻塞在18行的while(true),直到线程切换,很耗性能
    testLockThread线程:出于waitting状态,等待notify
    
    死锁:
    package cn.java.jvm;
    
    public class TestDeadThread implements Runnable {
        int a, b;
    
        public TestDeadThread(int a, int b) {
            this.a = a;
            this.b = b;
        }
    
        @Override
        public void run() {
            System.out.println("createDeadThread");
            synchronized (Integer.valueOf(a)) {
                synchronized (Integer.valueOf(b)) {
                    System.out.println(a + b);
                }
            }
        }
    
        public static void main(String[] args) {
            for (int i = 0; i < 100; i++) {
                new Thread(new TestDeadThread(1, 2)).start();
                new Thread(new TestDeadThread(2, 1)).start();
            }
        }
    }

    Jconsole点击检查死锁,会出现死锁的详情。

    thread-5的锁被thread-10持有,相反亦是,造成死锁。

  • 相关阅读:
    React父组件调用子组件
    ES6数组操作
    ant design mobile入坑记
    vue
    图片上传七牛
    CSS
    CSS矩形、三角形等
    使用POST下载文件
    http https协议
    前端网络必备知识
  • 原文地址:https://www.cnblogs.com/yaowen/p/9094463.html
Copyright © 2020-2023  润新知