Search code examples
javajnagarbage

When does JNA create FromNativeContext? (Tons of garbage)


When does JNA create FromNativeContext and how can I prevent the creation of these objects? I am creating millions in a few seconds with my application. I am using this direct-mapped class:

public final class Kernel32Direct {

    public static native boolean WriteProcessMemory(Pointer process, long address, Memory memory, int size, int written);

    public static native boolean ReadProcessMemory(Pointer process, long address, Memory memory, int size, int written);

    public static native Pointer OpenProcess(int desired, boolean inherit, int pid);

    public static native WinNT.HANDLE CreateToolhelp32Snapshot(WinDef.DWORD var1, WinDef.DWORD var2);

    public static native boolean Process32Next(WinNT.HANDLE var1, Tlhelp32.PROCESSENTRY32 var2);

    public static native boolean CloseHandle(WinNT.HANDLE var1);

    static {
        Native.register(NativeLibrary.getInstance("Kernel32", W32APIOptions.UNICODE_OPTIONS));
    }

}

Solution

  • A FromNativeContext object is created when JNA has to convert a primitive value into a Java object.

    Avoid using non-primitive types. When you use a type that derives from NativeMapped (i.e. HANDLE, which is a PointerType, and DWORD, which is an IntegerType) you're incurring additional overhead to convert from a Java object into a primitive integer or pointer.

    Use int rather than DWORD, and use Pointer rather than HANDLE.

    You're probably also getting some type conversion on the boolean parameter (defined in the W32APIOptions.DEFAULT_OPTIONS). Just use int in place of the boolean input, or leave out the type mapper (JNA should be able to convert an "int" return value into a Java boolean without an explicit type mapper).

    You should also use Pointer as a parameter type rather than Memory, but that's mostly about style.