new对象对空间有几部分:(运行时元数据(hash值,GC分代 锁状态标志 数组长度) 类型指针(Header)) 父类数据(实例数据,私有的数据也会存放在这里,但是被封装无法直接访问,取决于继承的定义)栈空间如何知道堆空间在哪(Hash值)虚拟地址 填充数据
赋值的时候是赋Hash值
属性如何摆放? 先放父类字段,再放其次的,宽度相同的也会放在一起。 可以通过参数设置子类数据在父类数据的空隙放置。
访问 句柄访问,。。。。访问定位:java栈本地变量表reference只想堆空间的对象 只需要移动句柄的指针,reference不用修改
指针直接访问
执行引擎 解释器,即使编译器,垃圾回收器。
执行引擎将字节码指令解释成环境语言(跨平台)
我们刚开始启动的时候用户就访问了,解释器热机快,次数多了有缓存指令了,就可以用JIT,语言快慢与语法规则无关,主要取决与编译器效率
JIT与AOT:即使编译器(动态)热点代码缓存 提前编译(静态)AOT运行之前就把字节码转化为机器码 Ahead Of Time Compiler 不选用,动态更加灵活一些且无跨平台,动态优化。
优化特征与即使编译器有关系 解释执行可以在编译器进行激进优化失败的备用方案,
热点代码缓存 方法调用计数器(存在直接运行,不存在+1 查看是否超过阈值),回边计数器
热度衰减:设定一定时间范围内
-Xint -XComp -Xmixed
JIT两个编译器 client(C1)简单可靠的优化,耗时短 方法内联A-》B 减少栈帧 栈上分配 server (默认 C2)耗时比较 长的优化,激进优化,优化后执行效率高
垃圾回收
垃圾收集的三个经典问题:
哪些需要回收,
垃圾G(Garbage)需要回收,对象不再被任何指针所指向的时候,把他认为是垃圾。重点回收Young 较少回收Old 基本不回收元空间 GC只存在堆和方法区
什么时候回收,
如何回收
判断是不是垃圾 不再被引用
引用+1 实现简单
垃圾回收算法
标记-清除(CMS)
凡是能和根关联的都不是垃圾,标记出来。但是会造成内存碎片。
复制
标记后整理,消除内存碎片 缺点 :对象很多,移动麻烦
可以在新生代使用。
标记-压缩
还是这一块内存空间有空的同时直接移动。尽量消除碎片化
指针碰撞
缺点:低于复制算法 调整指针 需要STW
分代收集
针对内存空间,
增量收集
分区算法
为什么需要回收:释放无用内存,整理碎片,整理内存,规避STW
早期GC手动回收
GC roots 有哪些 局部变量表的引用 JNI引用的对象 静态变量 锁 异常等