《深入理解java虚拟机》学习笔记(一)

 2019-12-22 10:43  阅读(975)
文章分类:JVM

说明

本系列为第一遍阅读的笔记,主要以摘录为主,等后面有一定经验后二刷、三刷,再根据自己经验对一些常用、常见、重点进行举例解释。

阅读目标

本次阅读主要以应付面试为主,目标是对jvm有个大概认知,知道常见面试问题中的答案及相关原理,根据读书内容整理出便于自己理解的思路及相关重点。详细目标如下:

  1. 内存分配和回收策略
  2. GC收集器
  3. GC算法
  4. 判断对象存活的方法
  5. 类加载器
  6. 类加载机制(类的加载过程)
  7. 类加载机制(类的初始化)
    (文末列出了网络上其它主要博文)

源码下载

github

概要

这里有一篇整理的不错的图
原文链接
2019120001236\_1.png

第一章

// todo

第二章

通过本章的学习,我们明白了虚拟机里面的内存是如何划分的,哪部分区域、什么样的代码和操作可能导致内存溢出异常。虽然Java有垃圾收集机制,但内存溢出异常离我们并不遥远, 本章只是讲解了各个区域出现内存溢出异常的原因
下一章将详细讲解Java垃圾收集机制为了避免内存溢出异常的出现都做了哪些努力。

拓展阅读
通过javap反汇编字节码文件,获取jvm执行的汇编代码文件,来反推jvm执行过程,进一步理解jvm内部栈、堆工作步骤和原理
javap的基本用法
java指令集

虚拟机里面的内存是如何划分的

2019120001236\_2.png

2019120001236\_3.png

2019120001236\_4.png

2019120001236\_5.png
jvm内存模型

哪部分区域、什么样的代码和操作可能导致内存溢出异常

  1. 2-3:不断创建无法自动回收的对象,导致后续操作无法获得更多足够内存抛出OutOfMemoryError异常

  2. 2-4:栈深度超过虚拟机允许最大深度,抛出StackOverflowError异常

    /** * 2-3 * VM Args:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError * @author zzm */ public class HeapOOM {

        static class OOMObject {
        }
    
        public static void main(String[] args) {
            List<OOMObject> list = new ArrayList<OOMObject>();
    
            while (true) {
                list.add(new OOMObject());
            }
        }
    }
    

    /** * 2-4 * VM Args:-Xss128k * @author zzm */ public class JavaVMStackSOF {

        private int stackLength = 1;
    
        public void stackLeak() {
            stackLength++;
            stackLeak();
        }
    
        public static void main(String[] args) throws Throwable {
            JavaVMStackSOF oom = new JavaVMStackSOF();
            try {
                oom.stackLeak();
            } catch (Throwable e) {
                System.out.println("stack length:" + oom.stackLength);
                throw e;
            }
        }
    }
    

    /** * 2-5 * VM Args:-Xss2M (这时候不妨设大些) * @author zzm */ public class JavaVMStackOOM {

           private void dontStop() {
                  while (true) {
                  }
           }
    
           public void stackLeakByThread() {
                  while (true) {
                         Thread thread = new Thread(new Runnable() {
                                @Override
                                public void run() {
                                       dontStop();
                                }
                         });
                         thread.start();
                  }
           }
    
           public static void main(String[] args) throws Throwable {
                  JavaVMStackOOM oom = new JavaVMStackOOM();
                  oom.stackLeakByThread();
           }
    }
    

    /** * 2-6 * VM Args:-XX:PermSize=10M -XX:MaxPermSize=10M * @author zzm */ public class RuntimeConstantPoolOOM { public static void main(String[] args) { // 使用List保持着常量池引用,避免Full GC回收常量池行为 List list = new ArrayList(); // 10MB的PermSize在integer范围内足够产生OOM了 int i = 0; while (true) { list.add(String.valueOf(i++).intern()); } } }

    /** * 2-7 * VM Args:-XX:PermSize=10M -XX:MaxPermSize=10M * @author zzm */ public class RuntimeConstantPoolOOM {

        public static void main(String[] args) {
            public static void main(String[] args) {
            String str1 = new StringBuilder("中国").append("钓鱼岛").toString();
            System.out.println(str1.intern() == str1);
    
            String str2 = new StringBuilder("ja").append("va").toString();
            System.out.println(str2.intern() == str2);
        }   }
    }
    

    /** * 2-8 * VM Args: -XX:PermSize=10M -XX:MaxPermSize=10M * @author zzm */ public class JavaMethodAreaOOM { public static void main(String[] args) { while (true) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(OOMObject.class); enhancer.setUseCache(false); enhancer.setCallback(new MethodInterceptor() { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { return proxy.invokeSuper(obj, args); } }); enhancer.create(); } }

        static class OOMObject {
    
        }
    }
    

    /** * 2-9 * VM Args:-Xmx20M -XX:MaxDirectMemorySize=10M * @author zzm */ public class DirectMemoryOOM {

        private static final int _1MB = 1024 * 1024;
    
        public static void main(String[] args) throws Exception {
            Field unsafeField = Unsafe.class.getDeclaredFields()[0];
            unsafeField.setAccessible(true);
            Unsafe unsafe = (Unsafe) unsafeField.get(null);
            while (true) {
                unsafe.allocateMemory(_1MB);
            }
        }
    }
    

参考资料

《JVM常见面试题及答案》https://blog.csdn.net/zd836614437/article/details/64126826

点赞(0)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> 《深入理解java虚拟机》学习笔记(一)

相关推荐