JVM中的对象

JVM中的对象

划分对象两种方式:
指针碰撞:java内存空间规整的请款下使用
空闲列表:java内存空间不规整的请款下使用

JVM中的对象

并发安全问题:频繁创建对象就会存在线程不安全问题。解决方案有两种:
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而言,它是使用直接指针访问进行对象访问的。
JVM中的对象

内存分配策略

-XX:SurvivorRatio=8,表示Eden和Survivor的比值,缺省为8 表示Eden:From(Survivor):To(Survivor)=8:1:1
-XX:SurvivorRatio=2表示2:1:1
设置两个Survivor区是为了解决碎片化的问题(复制回收算法)
JVM中的对象

  1. 对象有现在Eden区分配
  2. 大对象直接进入老年代
  3. 长期存活的对象进入老年代
  4. 动态对象年龄判断
  5. 空间分配担保
    JVM中的对象
    -Xms:20m 堆空间20m
    -Xmx:20m 堆最大空间20m
    -Xmn:10m 新生代(Eden区)10m
    -XX:+PrintGCDetails 打印GC日志
    -XX:+UseSeriolGC 一个垃圾回收器种类
    -XX:PretenureSizeThreshold=2m 超过2M的对象可以直接进入老年代

长期存活情况:
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

泛型

泛型擦除(为了实现)
弱记忆(版本的兼容)

JVM中的对象

上一篇:jvm中的新生代Eden和survivor区


下一篇:hdu5977 Garden of Eden 2016大连区域赛G题