类加载器和垃圾回收
jvm内存结构
私有线程:本地方法栈,操作方法栈 ,程序计数器
公有线程:方法区,堆
类加载
将java文件编译成class文件,通过类加载器加载到内存。类加载的过程包括了加载、验证、准备、解析、初始化五个阶段。
类加载器
概述
java应用程序由若干个.class文件组成,程序运行时需要调用不同的class文件来实现功能。程序启动时不会一次性加载所有class,会根据程序的需要通过Class Loader来动态加载某个class文件到内存,然后才能被其他class引用。
Bootstrap Class Loader:启动类加载器,只有在主动使用时才会加载。
Extension Class Loader:扩展类加载器,负责加载Java的扩展类库,默认加载JAVA_HOME/j re/lib/e x t/目录下的所有jar
App Class Loader:系统类加载器,负责加载应用程序class path目录下的所有jar和class文件。
自定义类加载器:新建一个类继承ClassLoader,重写它的findClass方法。重写loadClass方法可以打破双亲委派。
工作流程,双亲委派原则
目的:避免重复加载,父类加载一个类后,子类就没必要再次加载。
Bootstrap、Extension、App是爷、父、子的关系。
子要加载一个类的时候,会先让父加载,父让爷加载,爷加载的时候发现自己有这个类,就把这个类加载到内存。没有这个类的时候会推回子,由子将其加载到内存。可以避免重复加载同一个类。
垃圾回收
jvm在某个特定时间回自动进行GC
垃圾回收算法
标记清除:jvm会扫描所有的对象实例,通过根搜索算法,将活跃对象进行标记,jvm再一次扫描所有对象,将未标记的对象进行清除,只有清除动作,不作任何的处理,这样会产生很多碎片。
标记复制:jvm扫描所有对象,通过根搜索算法标记被引用的对象,之后会申请新的内存空间,将标记的对象复制到新的内存空间里,存活的对象复制完,会清空原来的内存空间,将新的内存最为jvm的对象存储空间。解决了碎片但是占用内存更大。
标记整理:标记清除后对内存进行整理,将所有存活对象统一向一端移动,这样解决了内存碎片问题
分代回收:年轻代主要使用标记复制,因为年轻代存活的对象少,只需要用复制法复制一小部分。老年代用标记清除和标记整理,因为老年代是年轻代筛选出来的对象,被标记比较高,需要删除的对象比较少