1.JVM主要组成部分

  • 类加载子系统

    • 将.class类型文件加载到内存中.

  • 运行时数据区

    • 方法区:存储类的结构信息,以及方法代码和静态变量.

    • 堆:动态分配对象实例.

      • 本地方法栈:存储本地方法的栈帧.

      • 虚拟机栈:存储了栈帧,保存了当前方法信息,包含局部变量表、操作数栈、方法返回地址、动态链接.

    • 程序计数器:一个指针,指向当前线程执行的字节码的行号.

    • 其中方法区和堆线程共享.栈,程序计数器线程不共享.

  • 执行引擎

    • 解释器:解释一行执行一行,并将热点代码缓存起来(JIT代码缓存).

    • 即时编译器:将热点代码编译为机器码.

    • 垃圾回收器:使用垃圾回收算法回收垃圾.

  • 本地方法接口

    • 都标注有Native关键字,操作系统本地方法.

  • 本地方法库

2.类加载子系统

  • 双亲委派机制:

    • 加载类的时候,自底向上检查是否加载,如果已经加载就使用,没有加载就向上传递.自顶向下尝试加载,如果没有加载就交给下层.如果都没有加载就抛出异常

  • 类加载器有哪些:

graph TD; A[启动类加载器] --> B[拓展类加载器]; B --> C[系统类加载器]; C --> D[自定义类加载器];

3.JVM运行时数据区

  • 方法区:

    • 存储类型描述,域描述,方法描述,JIT代码缓存,运行时常量池(JDK7之前包含字符串常量池,7之后不含).

    • JDK8之后方法区被移至本地内存,改名为元空间.

    • JDK8之前,方法区是概念,永久代是实现.JDK8之后,方法区是概念,原空间是实现.

    • 存放对象实例,逻辑上分为:年轻代,老年代,永久代

    • JDK8之前包括年轻代,老年代,永久代.JKD8之后元空间移至本地内存

    • 虚拟机栈存栈帧,栈帧中存局部变量表,操作数栈,方法返回地址,动态链接

  • 程序计数器

4.分代空间工作流程

新创建的对象进入伊甸园区,当伊甸园区满的时候,触发年轻代gc,将未回收的对象放入to区.当伊甸园区再次满触发年轻代gc的时候,将to区和伊甸园区未回收的对象一起移至from区,from区改为to区,并且对象年龄加1.当对象年龄超过15或to区满的时候,对象移动到老年代.当老年代满的时候,会触发老年代gc,同时触发Full gc从年轻代到老年代进行回收.如果这时内存还不够就抛出oom异常.

5.垃圾判定算法有哪些?垃圾回收算法有哪些?

  • 垃圾判断算法:

    • 引用计数法

    • 可达性分析法垃圾

  • 垃圾收集算法

    • 标记清除

    • 复制

    • 标记整理

    • 使用清除,复制,整理组合成为分代收集算法

6.引用有哪些

  • 强引用:只要不释放就不会回收

  • 软引用:内存溢出时回收

  • 弱引用:垃圾收集器一清理就回收

  • 虚引用:无法获取,用于跟踪垃圾回收过程

7.CMS和G1的

  • CMS:

    • 四个步骤

      • 初始标记

      • 并发标记

      • 重新标记

      • 并发清除

    • 作用:减少停顿时间

  • G1

  • 将内存分为四个区域,不是连续的空间,分别存放伊甸园区,幸存者区,老年代和大文件

  • 四个步骤:

    • 初始标记

    • 并发标记

    • 最终标记

    • 筛选回收

  • 作用:减少停顿时间,增加吞吐量

8.堆内存分为哪些区域,各区域存放对象的特点

  • 年轻代

    • 伊甸园区

      • 新创建的对象优先放置在此,垃圾回收最为频繁,当垃圾回收后,存活对象移动至from区,默认占新时代80%容量

      • from/to区

        • from:伊甸园区存活的对象移至此处,垃圾回收器再次回收后,年龄+1

        • to区:垃圾回收器触发时,与from互换,也就是说,from存活对象移动到to,之后to改为from,from改为to

  • 老年代

    • 默认占堆内存三分之二的空间,存放大对象,年龄到达15的对象,from/to区容纳不下的对象