##### JVM的启动流程: #####
1. 通过java+XXX或(javaw)命令启动java虚拟机;
2. 装载配置,会在当前的路径中寻找 JVM 的 config 配置文件;
3. 根据配置查找 jvm.dll 文件,这个文件就是 Java 虚拟机的主要实现;
4. 使用dll,初始化jvm,获得相关的接口;
5. 找到 main 方法执行;
##### JVM的基本结构: #####
![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzQ2NDk2NA_size_16_color_FFFFFF_t_70]
**PC寄存器:**
1. pc寄存器是线程私有的,在线程创建时创建;
2. 执行非native方法时,pc寄存器的值是当前需要执行指令的地址;执行native方法时,pc寄存器的值是undefined;
3. pc寄存器不会发生内存溢出,因为其存储的数据和所占空间大小不会随程序的执行而发生改变。
**方法区:**
1. 线程共享;
2. 保存已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据;
3. 在JVM规范中,没有强制要求方法区必须实现垃圾回收。很多人习惯将方法区称为“永久代”,是因为HotSpot虚拟机以永久代来实现方法区,从而JVM的垃圾收集器可以像管理堆区一样管理这部分区域,从而不需要专门为这部分设计垃圾回收机制。不过自从JDK7之后,Hotspot虚拟机便将运行时常量池从永久代移除了。
**方法堆:**
1. 所有线程都共享java堆;
2. 存储new出来的对象,以及数据(引用存放在Java栈中);
3. 垃圾回收器管理的主要区域;
**Java栈:**
1. 线程私有;
2. 每一次方法调用都会创建一个新的栈帧,并压栈;当方法执行完毕之后,便会将栈帧出栈。由此可知,线程当前执行的方法所对应的栈帧必定位于Java栈的顶部,以及使用递归方法的时候容易导致栈内存溢出的现象;
3. 对于小对象(一般几十个bytes),在没有逃逸的情况下,可以直接分配在栈上(直接分配在栈上,可以自动回收,减轻GC压力);大对象或者逃逸对象无法栈上分配;
[watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzQ2NDk2NA_size_16_color_FFFFFF_t_70]: /images/1615560095188.png