InternalThreadLocalMap类似于ThreadLocalMap,主要用于线程内部变量的存储,内部实现针对2种不同线程通过不同方式获取属性
属于FastThreadLocalAccess的线程构造InternalThreadLocalMap时直接构造填充32个对象,为什么会这样?
里面看到一段这样的代码加注释
// Cache line padding (must be public)
// With CompressedOops enabled, an instance of this class should occupy at least 128 bytes.
public long rp1, rp2, rp3, rp4, rp5, rp6, rp7, rp8, rp9;
cache line ,注释说开启指针压缩这个对象的实例内存占用至少要128字节,为什么?
对象占用内存,参考http://blog.csdn.net/aaa1117a8w5s6d/article/details/42400061
reference类型在32位系统上每个占用4bytes, 在64位系统上每个占用8bytes。
64位机器上reference类型占用8个字节,开启指针压缩后占用4个字节。
HotSpot的对齐方式为8字节对齐:
(对象头 + 实例数据 + padding) % 8等于0且0 <= padding < 8
这里设计到cache line的使用,cpu访问主存的规律:
1) cpu从来都不直接访问主存, 都是通过cache间接访问主存
2) 每次需要访问主存时, 遍历一遍全部cache line, 查找主存的地址是否在某个cache line中.
3) 如果cache中没有找到, 则分配一个新的cache entry, 把主存的内存copy到cache line中, 再从cache line中读取.
查阅资料后得出大概意思是cache line 读取会套锁,所以尽量避免锁住cache line时不会影响其他数据的访问,但是代码的意图还是没看明白...
public static final Object UNSET = new Object();
private InternalThreadLocalMap() {
super(newIndexedVariableTable());
}
private static Object[] newIndexedVariableTable() {
Object[] array = new Object[32];
Arrays.fill(array, UNSET);
return array;
}
UnpaddedInternalThreadLocalMap类
static ThreadLocal<InternalThreadLocalMap> slowThreadLocalMap; //static
/** Used by {@link FastThreadLocal} */
Object[] indexedVariables;