KO
|
EN
gitlite — search
Search
#typescript
#ai-agents
#ai
#dsh-plugin
#deepseek-harness
#open-source
#cli
#claude-code
#codex
#developer-tools
#react
#windows
nalloc
★ 74
Open GitHub ↗
Off-heap memory allocators for Java
Download README (.md)
Explore Similar Repositories
MedianFilter
:
Heap-free sliding window median filter for embedded C/C++ — O(n/2) insert, zero allocations, ideal for ADC noise removal on bare-metal and RTOS targets
heaplib
:
JVM Heap dump processing utility
go-interface-values
:
When storing a value in a Go interface allocates memory on the heap.
heap
:
Looking into the performance of heaps, starting with the Min-Max Heap
CVE-2019-6207
:
xnu kernel heap info leak
// repository documentation
Was this content helpful?
★ 0
(0 ratings)
Select Rating:
★
★
★
★
★
Submit Feedback
Recent Feedback
×
Download README
Do you want to download the
README.md
file for
nalloc
?
Download (.md)
# nalloc - off-heap memory allocators for Java [](https://drone.io/github.com/alaisi/nalloc/latest) Nalloc contains factories for allocating Java objects from native heap and memory mapped files. Basically `void*` and `mmap` in Java. Off-heap storage is usually required with huge datasets (eg. caches and data grids) or with systems with hard latency requirements (eg. stock trading). Instantiating tens of millions of data entries from JVM heap is slow and likely to cause GC trashing. Off-heap storage for N entries can be instantiated in O(1) and data can be handled in pre-allocated arrays with direct pointer access. Nalloc uses almost no JVM heap once initialized and is suitable for systems requiring "garbage free" design. ## Download Nalloc is available on [Maven Central](http://repo1.maven.org/maven2/com/github/alaisi/nalloc/). ```xml <dependency> <groupId>com.github.alaisi.nalloc</groupId> <artifactId>nalloc</artifactId> <version>0.1.Alpha1</version> </dependency> ``` ## Usage ### Hello world ```java NativeHeapAllocator allocator = NativeHeapAllocator.Factory.create(Message.class); Pointer<Message> ptr = allocator.malloc(Message.class); Message message = ptr.deref(); message.content("Hello world!"); System.out.println(message.content()); ptr.free(); ``` ### Native heap Access to native heap is provided by [`com.github.nalloc.NativeHeapAllocator`](https://github.com/alaisi/nalloc/blob/master/src/main/java/com/github/nalloc/NativeHeapAllocator.java). Pointers to native memory are eligible for GC, but the data referred to is not. Allocating a single instance: ```java NativeHeapAllocator allocator = NativeHeapAllocator.Factory.create(MyStruct.class); Pointer<MyStruct> ptr = allocator.malloc(MyStruct.class); ``` Allocating 90 million instances initialized to zero: ```java Array<MyStruct> array = allocator.calloc(90000000, MyStruct.class); ``` Resizing an array to 1 million: ```java Array<MyStruct> array = ... array = allocator.realloc(array, 1000000); ``` ### Memory mapped files Access to memory mapped files is provided by [`com.github.nalloc.MmapAllocator`](https://github.com/alaisi/nalloc/blob/master/src/main/java/com/github/nalloc/MmapAllocator.java). Pointers to mmapped files provide access to objects that are transparently written to a file. As this is equivalent of POSIX `MAP_SHARED`, MmapAllocator can also be used as an IPC channel to interact with programs written in C/Python/Ruby/etc. Mapping with `MAP_ANOYMOUS` without a backing file and mapping a buffer with `MAP_PRIVATE` are also implemented. Mapping a file to memory with preallocated space for 1 million instances of MyStruct: ```java MmapAllocator allocator = MmapAllocator.Factory.create(MyStruct.class); Array<MyStruct> messages = allocator.mmap(new File("/tmp/my-index"), 1000000, MyStruct.class); // write to array index 5000 MyStruct my = messages.get(5000); my.myAge('X'); ``` Mapping a `java.nio.ByteBuffer`: ```java ByteBuffer buffer = ByteBuffer.allocateDirect(4096).order(ByteOrder.nativeOrder()); Array<MyStruct> array = allocator.mmap(buffer, MyStruct.class); ``` Anonymous mapping without a file for 1000 instances: ```java Array<MyStruct> array = allocator.mmap(1000, MyStruct.class); ``` Mutating an mmapped array with `java.nio.ByteBuffer`: ```java Array<MyStruct> array = ... ByteBuffer buffer = allocator.toBytes(array); java.nio.channels.SocketChannel channel = ... channel.read(buffer); ``` ### Pointers Objects returned by the allocators are [`com.github.nalloc.Pointer`](https://github.com/alaisi/nalloc/blob/master/src/main/java/com/github/nalloc/Pointer.java) and its subclass [`com.github.nalloc.Array`](https://github.com/alaisi/nalloc/blob/master/src/main/java/com/github/nalloc/Array.java). These are pointers to native memory that must be freed after use, otherwise memory (and possibly file descriptors) are leaked. Freeing a pointer: ```java Pointer<MyStruct> ptr = allocator.malloc(MyStruct.class); ptr.free(); ``` Pointer extends `java.lang.AutoCloseable`, so it can be used in a try-with-resources block (mimicking C++ RAII): ```java try(Array<MyStruct> ptr = allocator.calloc(16, MyStruct.class)) { // do something with ptr } // ptr is now freed ``` Pointers provide all the type safety and bound checking of native C pointers: none. Bugs in handling pointers can (and most likely will) segfault the JVM. ### Structs Off-heap objects are modelled as c-style structs that have state but no behavior. Java representation is an interface annotated with [`@com.github.nalloc.Struct`](https://github.com/alaisi/nalloc/blob/master/src/main/java/com/github/nalloc/Struct.java). Implementation for the interface is generated by the allocator and is based only on the `Struct` annotation value. ```java @Struct({ @Field(name="id", type=Type.LONG) @Field(name="type", type=Type.String, len=10) }) public interface Message { long id(); void id(long id); String name(); void name(String name); } ``` Strings and arrays have a fixed length specified in `Field.len`. ```java @Struct({ @Field(name="history", type=Type.LONG, len=10) @Field(name="header", type=Type.String, len=10) }) public interface Request { long[] history(); void history(long[] id); char[] header(); void header(char[] header); } ``` `Struct.c` creates C-compatible memory layout and `Struct.pad` pads memory length. ```java @Struct(c=true, pad=8, value={ @Field(name="type", type=Type.CHAR) @Field(name="body", type=Type.String, len=10) }) public interface Response { char type(); // single byte char void type(char type); String body(); // max 9 single byte chars and null terminator void body(String body); } ``` Nested struct and struct arrays are supported with `Type.STRUCT`. ```java @Struct({ @Field(name="headerType", type=Type.LONG), @Field(name="content", type=Type.STRING, len=16) }) public interface Header { long headerType(); void headerType(long type); String content(); void content(String content); } @Struct({ @Field(name="header", type=Type.STRUCT, struct=Header.class), @Field(name="headers", type=Type.STRUCT, struct=Header.class, len=32) }) public interface Message { Header header(); Array<Header> headers(); } ```