类加载器ClassLoader

负责加载class文件,class文件在文件开头有特定的标识,将class文件字节码内容加载到内存中,并将这些内容转换成方法区中的运行时数据结构;ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定;

image-20220620210444500.png

类加载器的类型:

启动类加载器(Bootstrap) C++
扩展类加载器(Extension) Java
应用程序类加载器(APPClassLoader),java也叫系统类加载器,加载当前应用的classpath的所有类

双亲委派机制
我们在使用一个类时,ClassLoader首先从bootstrap、extension、application一次向下加载;
即先从最高级的类加载器寻找class文件,找不到再依次向下寻找;

沙箱安全机制
防止恶意编写代码污染java源代码(String、Object类);

线程的六种状态:
创建、就绪、阻塞、等待、计时等待、终止

native:调用底层第三方操作系统库、c语言的方法库;

PC寄存器

每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码
(用来存储指向下一条指令的地址,也即将要执行的指令代码),由执行引擎读取下一条指令,
是一个非常小的内存空间,几乎可以忽略不计,是当前线程所执行字节码的行号指示器;

方法区

存储了每个类的结构信息;
方法区是规范,在不同的虚拟机里有不同的实现,最典型的就是永久代(PermGen Space)和元空间(MetaSpace);

静态变量加载进方法区;
加载顺序:静态代码块 > 构造块 > 构造方法;

虚拟机栈

栈管运行,堆管存储
8中基本类型的变量 + 对象的引用变量 + 实例方法都是在函数的栈内存中分配
java中把方法压入栈中叫做栈帧

1、Eden、SurvivorFrom复制到SurvivorTo,年龄+1
首先,当Eden区满的时候会触发一次gc,把活着的对象拷贝到SurvivorFrom区,当Eden触发第二次gc时,会自动扫描eden、from区,对这两个区域进行垃圾回收,经过这次回收还活着的对象,直接复制到to区域(如果有对象已经达到了老年代的标准,则复制到老年代的区域),同时把这些对象的年龄+1

2、清空Eden、SurvivorFrom
然后,清空Eden、SurvivorFrom中的对象,也即复制之后有交换,谁空谁是to

3、SurvivorFrom和SurvivorTo交换
最后,SurvivorFrom和SurvivorTo互换,原SurvivorTo成为下一次gc的SurvivorFrom区;部分对象会在from和to区中来回复制,如此交换15次(由jvm参数MaxTenringThreshold决定,这个参数默认是15),最终还能存活,就进入老年代

java8之后,元空间并不存在于jvm中,而是使用本机物理内存;

-Xms :设置初始分配大小,默认为物理内存的1/64
-Xmx:最大分配内存,默认物理内存的1/4
-XX:+PrintGCDetails

GC

gc之后有交换,谁空谁是to

分代收集算法: 次数上频繁回收Young区、次数上较少回收Old区、基本不动元空间

四大算法:
1、引用计数法
2、复制算法(Copying):年轻代中的YGC,不会产生内存碎片,耗空间;
3、标记清除(Mark-Sweep):老年代,两个阶段:先标记要回收的对象,然后通过一回收这些对象;
不需要额外的空间;两次扫描,耗时严重;会产生内存碎片;
4、标记压缩(Mark-Compact):老年代,没有内存碎片;需要移动对象的成本;
image.png