帮助我理解一些事情。
使用.. 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);
}
请帮助我理解
答案 0 :(得分:2)
Unsafe#allocationMemory
的JavaDoc说:
分配给定大小的新的本机内存块(以字节为单位)。的的 内存的内容未初始化;他们通常会 垃圾即可。生成的本机指针永远不会为零,并且将是 对齐所有值类型。通过调用#freeMemory来处理这个内存,或者用#reallocateMemory调整它的大小。
这意味着当您将byte
放在那里并阅读char
时,您会获得额外的垃圾字节。