0

帮助我理解一些事情。

使用 ..import sun.misc.Unsafe;

如果我需要将字符放入0-127某个内存地址,以防止超出范围的字符,我会这样做

if (0 != (c & 0xFF80)) {
    throw new RuntimeException("Only Ascii characters are supported. 0-127.");
} else {
    // Since Java's chars are 16 bits long, i cast it 
    // to byte (8 bits) and then `putByte()`
    UNSAFE.putByte(address, (byte) c);
}

当我的测试检查该内存中的内容时

    char c1 = Ascii.a;
    asciiEncoder.encode(address, c1);
    assertThat(unsafe.getChar(address), is(c1));

这个测试似乎在某些机器上通过和失败。让我重复一遍 - 这适用于某些 MAC,而不适用于其他 MAC,某些 Windows 而不是其他的。

什么是失败?返回与“a”不同的字符。

据我了解,如果在分配时没有清理内存,这是可能的,但这不解决这个问题吗?

@Before
public void setUp() {
    address = unsafe.allocateMemory(64); // Isn't this mem clean?
} 

如果我将其更改为 8 位,则测试始终通过

@Before
public void setUp() {
    address = unsafe.allocateMemory(8);
} 

请帮我理解

4

1 回答 1

2

JavaDocUnsafe#allocationMemory说:

分配给定大小(以字节为单位)的新本机内存块。内存内容未初始化;它们通常是垃圾。生成的本机指针永远不会为零,并将针对所有值类型对齐。通过调用 #freeMemory 释放此内存,或使用 #reallocateMemory 调整其大小。

这意味着当您放在byte那里并回读时char,您会得到额外的垃圾字节。

于 2013-05-23T20:39:45.067 回答