类加载器
分为,应用程序加载器,扩展类加载器,根加载器,jvm自带加载器
类的加载过程为双亲委派机制:如果加载一个类,他会首先找应用程序加载器->扩展类加载器->根加载器一层一层的加载,如果有则加载没有在加载自己的,这样可以保证安全
打破双亲委派机制:自定义一个ClassLoader并重写loadClass方法,如spi,数据库我们提供接口,数据库厂商提供实现
寄存器
每个线程都有一个程序计数器,线程私有
本地方法栈
native关键字修饰,就是Java达不到的,如thread中的start方法,Java基本不怎么操作硬件等,所以需要c,c++的库调用本地方法接口JNI,会在内存中开辟一块区域为native method stack 最终去加载本地方法库
栈
栈内存,主管程序运行,生命周期和线程同步,线程结束,栈释放,不存在垃圾回收
存放:八大基础类型+对象引用+实列的方法
方法区
线程共享的,存储,final,static,Class,常量池
堆
对象实例,数组
new关键字的时候我们需要做什么
堆:
存放对象,数组
里面主要包含年轻代,老年代,永久区(元数据区)
年轻代:存放新创建的对象,如果erdn满了就进行一次轻GC,然后会到幸存区(from,to)
老年代:存放幸存区默认为存活了15的对象存放到老年区,会进行重GC(或者system.gc)
清除算法:复制算法,标记清楚,标记整理
怎么判断对象是否需要清楚,可达性分析:通过获得“gc root”,然后遍历树,看有没有关联
复制算法:把to区全部置为空,from区保存幸存对象默认为15次就会到老年区,以空间换时间
标记清楚:第一遍,标记可以达到的对象,第二遍清楚
标记整理:第一遍,标记可以达到的对象,第二遍清楚,整理内存空间(假设全部左移)
几种算法用在哪里
年轻代:复制算法,因为存放的对象多,消失快
老年代:想标记清楚几次后,在标记整理,对象多,消失的不快
JVM优化
1.增加内存看是否溢出
2.dump出文件(XX:+HeapDumpOnOutOfMemeryError)通过pojer工具查询,看那个对象在内存中异常,及错误日志
怎么找出文件是否是需要清除的
可达性分析:找出gc root然后遍历树,如果有关联的就不清楚,没有关联的清除,因为没有关联的所以可能不会引用
怎么找到gc root通过查找运行中的方法区中常量池,栈中的本地变量等