Reputation: 96481
Help me understand something.
Using .. import sun.misc.Unsafe;
If i need to put a character 0-127
to some memory address, in order to prevent out of range chars, i do this
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);
}
When my test checks what's in that memory
char c1 = Ascii.a;
asciiEncoder.encode(address, c1);
assertThat(unsafe.getChar(address), is(c1));
This test seems to pass and fail on some machines. Let me repeat that - this works on some MACs and not the others and some Windows and not the others.
What is failing? Character different to 'a' is returned.
As i understand it, this is possible if upon allocation, memory is not cleaned up, but does not this take care of this?
@Before
public void setUp() {
address = unsafe.allocateMemory(64); // Isn't this mem clean?
}
If i change this to 8 bits, test passes always
@Before
public void setUp() {
address = unsafe.allocateMemory(8);
}
Please help me understand
Upvotes: 0
Views: 165
Reputation: 10161
JavaDoc for Unsafe#allocationMemory
says:
Allocates a new block of native memory, of the given size in bytes. The contents of the memory are uninitialized; they will generally be garbage. The resulting native pointer will never be zero, and will be aligned for all value types. Dispose of this memory by calling #freeMemory , or resize it with #reallocateMemory .
Which means when you put byte
there and read char
back you get extra byte of garbage.
Upvotes: 2