Skip to main content

java unsafe

· 2 min read

背景

java的unsafe包是有很多底层的api暴露出来,举例,java的netty就大量使用这个api

例子

下面是java的unsafe包里面的allocateMemory方法.

public class UnsafeDemo {

public static void main(String[] args) {
var unsafe = getUnsafe();
var memory = unsafe.allocateMemory(100);
System.out.println(memory);
}

private static Unsafe getUnsafe() {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
return (Unsafe) field.get(null);
} catch (Exception e) {
return null;
}
}
}

这里memory 返回的是一个地址

实际上是调用Unsafe_AllocateMemory0

UNSAFE_ENTRY(jlong, Unsafe_AllocateMemory0(JNIEnv *env, jobject unsafe, jlong size)) {
size_t sz = (size_t)size;

assert(is_aligned(sz, HeapWordSize), "sz not aligned");

void* x = os::malloc(sz, mtOther);

return addr_to_java(x);
} UNSAFE_END

最后调用的是glibc 的malloc

void* os::malloc(size_t size, MEMFLAGS memflags, const NativeCallStack& stack) {

// Special handling for NMT preinit phase before arguments are parsed
void* rc = NULL;
if (NMTPreInit::handle_malloc(&rc, size)) {
// No need to fill with 0 because DumpSharedSpaces doesn't use these
// early allocations.
return rc;
}

DEBUG_ONLY(check_crash_protection());

// On malloc(0), implementations of malloc(3) have the choice to return either
// NULL or a unique non-NULL pointer. To unify libc behavior across our platforms
// we chose the latter.
size = MAX2((size_t)1, size);

// For the test flag -XX:MallocMaxTestWords
if (has_reached_max_malloc_test_peak(size)) {
return NULL;
}

const size_t outer_size = size + MemTracker::overhead_per_malloc();

// Check for overflow.
if (outer_size < size) {
return NULL;
}

ALLOW_C_FUNCTION(::malloc, void* const outer_ptr = ::malloc(outer_size);) <-- malloc 分配内存
if (outer_ptr == NULL) {
return NULL;
}

void* const inner_ptr = MemTracker::record_malloc((address)outer_ptr, size, memflags, stack);

if (DumpSharedSpaces) {
// Need to deterministically fill all the alignment gaps in C++ structures.
::memset(inner_ptr, 0, size);
} else {
DEBUG_ONLY(::memset(inner_ptr, uninitBlockPad, size);)
}
DEBUG_ONLY(break_if_ptr_caught(inner_ptr);)
return inner_ptr;
}

相关阅读