逐步细化
静态链接:静态方法(符号引用)替换为内存指针或者句柄直接引用)
动态链接:程序期间将符号引用替换为直接引用
对象头:
指针压缩:
-XX:+UseCompressedOops 开启指针压缩
减少内存消耗;大指针在主内存 缓存间移动数据,占用带宽大 GC压力大
jvm通过对对象指针存入堆内存时进行压缩编码32位,取到cpu寄存器 解码方式优化35位
堆内存大于32g,压缩指针失效,强制使用64位对java对象寻址
小于4g 不需要启动指针压缩 直接去除高32位地址,使用低虚拟空间
Launcher
单例
内存分配
逃逸分析:
在方法被定义后可能被外部方法引用
不会逃逸的对象可在栈上分配内存,方法结束时跟随栈内存一起被回收掉
默认开启- XX:DoEscapeAnalysis 7默认开启
标量替换:不会逃逸 且对象可进一步分解,jvm不会创建该对象,分解若干成员变量
-XX:EliminateAllocations
标量与聚合量:标量不能分解掉量,基本数据类型 reference类型
聚合量:可分解掉量,对象
堆分配:
内存模型
栈帧内存空间:独立
参数:
-Xms -Xmx -Xmn
-XX:MaxMetaspaceSize元空间max值,默认 -1 不限制
-Xss 栈大小默认1m,值越小栈帧越小,512k,jvm开启线程越多
-XX:MetaspaceSize 元空间初始大小 字节为单位 21M ,到达触发full gc,收集器对该值调整,释放了大量空间则调低,释放很少空间 不超max提高该值
双亲委派:父加载器
类型
引导类加载器:jre的lib核心类
扩展类加载器:ext
应用程序加载器:appClassLoader ,classpath,target包
自定义加载器:
过程
appClassLoader urlClassLoader loadClass(全类名)
findLoadedClass已经加载的类c
parent.loadClass(name,resolve:false);加锁 sync ;
父的loadClass (extClassLoader循环调super)
findBootstrapClassOrNull引导类加载器
已经加载的类去
findClass(); 可打破双亲委派,跳过super
urlClassLoader: path 类路径
ucp.getResource加载类
defineClass
打破
tomcat
web容器,不同应用程序可能会依赖同一三分库的不同版本;
commonLoader:基本类加载器,class可被tomcat本身及wabapp访问
sharedLoader:各webapp共享类加载器, 加载路径中class对于所有webapp可见,对tomcat容器不可见
catalinaLoader:tomcat容器私有类加载器,加载路径中class对webapp不可见
webappClassLoader:各webapp私有类加载器,加载路径中的class文件对当前webapp见,每个war有自己的webappClassLoader,互相隔离,不同war包应用引入不同spring版本
原因
沙箱安全机制:自己写的类不会被加载,防止核心api库被随意篡改
避免类重复加载:父已经被加载类该类,没必要再加载一次
全盘委托:
当一个classload装载一个类时,除非显示使用另一个classloader,该类所依赖及引用的类也由这个classloader载入
自定义类加载器
继承java.lang.ClassLoader类
public class FindClassLoader {
static class MyClassLoader extends ClassLoader{
private String classPath;
public MyClassLoader(String classPath){
this.classPath =classPath;
}
private byte[] loadByte(String name) throws Exception{
name = name.replaceAll("\\.","/");
FileInputStream fis = new FileInputStream(classPath+"/"+name+".class");
int len = fis.available();
byte[] data = new byte[len];
fis.read(data);
fis.close();
return data;
}
protected Class<?> findClass(String name) throws ClassNotFoundException{
try {
byte[] data = loadByte(name);
//字节数组转class对象,字节数组是class文件读取后最终的字节数组
return defineClass(name,data,0,data.length);
}catch (Exception e){
e.printStackTrace();
throw new ClassNotFoundException();
}
}
}
public static void main(String[] args) throws Exception{
//初始化自定义类加载器 先初始化父类classloader;会把自定义类加载器的父加载器=appClassLoader
MyClassLoader classLoader = new MyClassLoader("读取哪个路径");
Class clazz = classLoader.loadClass("类全路径");
Object obj = clazz.newInstance();
Method method=clazz.getDeclaredMethod("哪个方法",null);
method.invoke(obj,null);
System.out.println(clazz.getClassLoader().getClass().getName());
}
}