目录
1、JVM运行时数据区包括哪些区域
堆(线程共享、Java虚拟机(线程私有)、本地方法栈(线程私有)、程序计数器(线程私有)、方法区(线程共享)
2、.class文件怎么被JVM加载并运行

1、加载.class文件到内存中
2、类对象(class)存在方法区,以便以后new对象的时候可以从这里找到类的模板,进行对象的创建
3、new出来的对象都存放在堆内存
4、每个线程都会在Java虚拟机栈中分配一个与之对应的内存空间,栈中存的是线程对方法的调用层级
5、本地方法栈存的是本地方法的调用层级
6、程序计数器保存的是当前线程执行的行号
3、JVM类加载的过程

1、加载:在当前的classpath下找到的所有.class文件,读取到内存中
2、验证:验证.class是否符合JVM的规范
3、准备:为类中定义的静态变量分配内存并设置初始值
4、解析:是Java虚拟机将常量池内的符号引用替换为直接引用的过程,也就是初始化常量的过程
5、初始化:执行代码中真正的赋值操作
6、使用:new对象的过程,执行构造方法,以及父类的构造方法
当构造方法执行完毕,对象的初始化完成,一个真正可用的对象才被创建出来
7、卸载:程序停止时,从JVM中卸载
4、双亲委派模型

1、当创建一个类时,先从应用程序加载器开始向上转发,一直到启动加载
2、启动加载器在自己的路径下找,看有没有这个类,有则加载,没有则向下转发给扩展加载器
3、扩展加载器在自己的路径下找,看有没有这个类,有则加载,没有则向下转发给应用程序加载器
4、应用程序加载器在自己的路径中找到类并加载
但双亲委派机制可以被打破,比如JDBC,可以直接加载数据库厂商提供的jar包,不会向上传递加载
5、垃圾回收的过程

1、所有的对象创建后都在新生代的Eden区
2、当发生第一轮GC后,如果对象没有被回收将会复制到幸存者区(from区),把Eden区内存全部清空
3、从第二轮开始,每次GC都会把eden区和from区的对象复制到to区
4、from和to进行互换位置
5、当经历一轮GC之后,对象没有被回收,则年龄加1(长大一岁)--保存在对象头里
6、当对象的年龄到了15岁(默认15,但可以设置)之后,就会被移到老年区
7、但是当一个很大的对象被创建时,Eden区放不下,会直接进入老年区
6、垃圾收集器
所有对垃圾收集器的优化,最终都是解决STW的问题。
刚开始是串行收集器,但由于内存变大之后串行操作,进行垃圾回收就会造成STW的时间比较长,于是为了解决效率问题,使用并行收集器。但内存空间越来越大,并行的STW时间也会很长,就有了CMS收集器。
CMS收集器是基于"标记-清除"算法实现的:
1、初始标记(STW,标记 GC Roots 直接引用对象)
2、并发标记(与应用线程并行,遍历引用链)
3、重新标记(STW,修正并发标记期间的变动)
4、并发清除(与应用线程并行,清理垃圾对象)
现在主流使用G1 收集器,它是 Region 化的整堆收集器,基于标记 - 整理 + 复制算法,可预测停顿时间,解决了 CMS 的内存碎片问题