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

版权声明:没有版权,转载署名即可,有事联系我邮箱[email protected],其他消息我收不到。 https://blog.csdn.net/u010414666/article/details/80829063

说明

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

阅读目标

本次阅读主要以应付面试为主,目标是对jvm有个大概认知,知道常见面试问题中的答案及相关原理,根据读书内容整理出便于自己理解的思路及相关重点。详细目标如下:
1. 内存分配和回收策略
2. GC收集器
3. GC算法
4. 判断对象存活的方法
5. 类加载器
6. 类加载机制(类的加载过程)
7. 类加载机制(类的初始化)
(文末列出了网络上其它主要博文)

源码下载

github

概要

这里有一篇整理的不错的图
原文链接
这里写图片描述

第一章

// todo

第二章

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

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

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

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述
jvm内存模型

扫描二维码关注公众号,回复: 3814319 查看本文章

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

  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<String> list = new ArrayList<String>();
        // 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

猜你喜欢

转载自blog.csdn.net/u010414666/article/details/80829063