2

<code root>/dalvik/vm/Sync.cpp,有一个struct Monitor

struct Monitor {
    Thread*     owner;          /* which thread currently owns the lock? */
    int         lockCount;      /* owner's recursive lock depth */
    Object*     obj;            /* what object are we part of [debug only] */

    Thread*     waitSet;    /* threads currently waiting on this monitor */

    pthread_mutex_t lock;

    Monitor*    next;

    /*
     * Who last acquired this monitor, when lock sampling is enabled.
     * Even when enabled, ownerMethod may be NULL.
     */
    const Method* ownerMethod;
    u4 ownerPc;
};

我不明白为什么Monitor要按 8 个字节对齐。我认为它应该对齐 4 个字节,因为其中的所有成员(即指针int& pthread_mutex_t)的长度都是 4 个字节。

4

1 回答 1

3

该问题没有明确显示它,但是通过 8 字节对齐,您可能是指代码的这一部分,并Misaligned monitor检查:

Monitor* dvmCreateMonitor(Object* obj)
{
    Monitor* mon;
    mon = (Monitor*) calloc(1, sizeof(Monitor));
    if (mon == NULL) {
        ALOGE("Unable to allocate monitor");
        dvmAbort();
    }
    if (((u4)mon & 7) != 0) {
        ALOGE("Misaligned monitor: %p", mon);
        dvmAbort();
    }

原因是 Dalvik 使用了薄锁。锁是对象的 32 位值,低 3 位用于编码锁状态:一位用于瘦/胖锁状态,两位用于散列状态。Monitor指向自身的指针只剩下 29 位。

来自同一来源

锁定值本身存储在 Object.lock 中。锁的 LSB 对其状态进行编码。清除后,锁处于“瘦”状态,其位格式如下:

[31 ---- 19] [18 ---- 3] [2 ---- 1] [0]
 lock count   thread id  hash state  0

设置后,锁处于“胖”状态,其位格式如下:

 [31 ---- 3] [2 ---- 1] [0]
   pointer   hash state  1

作为参考,这里是描述瘦锁的论文:Thin Locks: Featherweight Synchronization for Java

在评论中,您询问对齐是如何完成的。C 标准只要求分配器返回可用于任何类型分配的地址。来自 C99 §7.20.3(内存管理功能):

如果分配成功,则返回的指针经过适当对齐,以便可以将其分配给指向任何类型对象的指针,然后用于访问已分配空间中的此类对象或此类对象的数组(直到空间被显式释放) .

默认情况下,malloc/calloc/realloc在 32 位 ARM 系统上返回 8 字节对齐的块。我相信Misaligned monitor,如果分配器被替换为不返回 8 字节对齐块的版本,那么检查是否会像防御性代码一样快速失败。

于 2013-09-26T08:37:42.670 回答