划分对象两种方式:
指针碰撞:java内存空间规整的请款下使用
空闲列表:java内存空间不规整的请款下使用
并发安全问题:频繁创建对象就会存在线程不安全问题。解决方案有两种:
1.对分配内存空间的操作进行同步处理,CAS加失败重试机制保证保证更新操作原子性。
2.分配缓冲:给每个线程分配独立空间(Java堆中申请一小块私有内存),也就是本地线程分配缓冲(Tread Local Allocation Buffer,TLAB),开启 -XX:+UseTLAB,在自己Buffer分配,空间不够重新在Eden区申请一块继续使用。
TLAB可以让每个应用线程拥有专属的分配指针来分配空间(Eden区,默认Eden的1%),减小同步开销。
TLAB只是让每个线程有私有的分配指针,但底下存对象的内存空间还是给所有线程访问的,只是其他线程无法在这个区域分配而已。当一个TLAB用满(分配指针top撞上分配极限end了),重新申请一个TLAB.
在HotSpot虚拟机中,对象的内存布局分为:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)
对象头分配两部分,一是自身运行时数据(哈希吗HashCode)、GC分带年龄、锁状态标志、线程持有锁、偏向线程ID、偏向时间戳等。
另一种类型指针,即只想它的类元素指针,虚拟机通过这个指针来确定是哪个类的实例
对齐填充起到占位符的作用。对象的大小必须是8个字节。实例数据7个字节 填充1个,1个填充7个。
句柄:Java堆中划分一块内存作为句柄池,reference中存对象句柄地址,句柄中包含对象实例数据与类型数据各自的具体地址信息。
直接指针:reference直接存对象地址。
句柄的好处对象移动(垃圾回收移动对象)时只改变实例数据指针,而reference本身不需要修改。直接指针方式最大好处就是速度更快,减少指针定诶的时间开销。对Sun HotSpot而言,它是使用直接指针访问进行对象访问的。
-XX:SurvivorRatio=8,表示Eden和Survivor的比值,缺省为8 表示Eden:From(Survivor):To(Survivor)=8:1:1
-XX:SurvivorRatio=2表示2:1:1
设置两个Survivor区是为了解决碎片化的问题(复制回收算法)
长期存活情况:
Eden区8m占满,再分配1m对象,Eden区会发生MinGC.
存活对象进入from区,年龄+1,再来垃圾回收则进入to区,年龄再+1。
再次进行垃圾回收,对象返回from区,年龄再+1, from和to区反复,因为from和to区采用复制回收算法的原因。
年龄达到15岁,属于长期存活对象,进入老年代。
动态对象年龄判断:
from和to区年龄加起来是from年龄的一半,就可以提前晋级,进入老年代。
空间分配担保:HandlePromotionFailure, 不用考虑老年代空间不够,不用考虑发生FullGC,如果担保失败或内存不够也会进行一次FullGC
FullGC:当老年代空间不足时候,有from或to区升级进入老年代的时候,将会执行FullGC
泛型擦除(为了实现)
弱记忆(版本的兼容)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。