Chronicle-Core reaches under the JVM with OS.map, off-heap writes and deterministic closes
Low level access to native memory, JVM and OS.
At a glance
- What is it?
- Chronicle-Core is the low-level Java library from Chronicle Software that exposes operating system calls, off-heap memory access, memory mapped files and reference counted resources. The project itself warns that it should be used with caution, because the operations it offers can produce complicated problems when misused.
- Who is it for?
- Chronicle-Core fits a Java engineer writing latency sensitive or allocation constrained code who needs off-heap access, deterministic resource release and system level primitives in one dependency rather than several. It does not fit an application developer who has no reason to leave the heap, and the project's own caution about misuse should be read as a warning about the whole API surface, not only the mapping calls.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 31 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A library whose own documentation tells you to be careful
Chronicle-Core is described as an advanced low-level library that equips developers with tools to interact with the operating system, manage memory, handle resources, and more. The next sentence is the one to remember: it should be used with caution due to its low-level operations which, if misused, can lead to complex issues.
That is unusual framing for a library summary, and it is accurate rather than decorative. The feature list runs from operating system calls through JVM access methods to memory mapped files, and each of those lets you bypass a layer the JVM normally protects you from. Mapping a file and writing a long to a raw offset is not a convenience API. It is a tool for people who already know exactly what they are doing and want the JVM out of the way.
The primary language is Java and the licence is Apache-2.0, which is permissive and unusual for this class of library. The artefact coordinates are net.openhft/chronicle-core on Maven Central, and the javadoc is published. The default branch is ea, which tells you something about the release model: this project develops on a rolling branch rather than cutting from master.
The package structure in the repository shows a library with serious testing discipline. Alongside src there are assertions-disabled and assertions-enabled directories, checked-exceptions, a benchmarks directory, docs, and a system.properties file at the root. Splitting the assertion behaviour into two source sets, with a separate checked-exceptions package, is the kind of layout you see in codebases where the build matrix and the runtime configuration are treated as first class concerns.
OS calls, JVM access, and the mapping calls that can go wrong
The Operating System Calls section covers the plain accessors first. The library provides access to various system calls such as retrieving the process ID, checking the operating system, and obtaining the hostname, among others:
int processId = OS.getProcessId();
boolean isWindows = OS.isWindows();
String hostname = OS.getHostName();Those three are unremarkable and useful. The interesting part is the memory mapped file interface, which is described as useful for high-performance I/O operations:
FileChannel fc = new CleaningRandomAccessFile(fileName, "rw").getChannel();
long address = OS.map(fc, MapMode.READ_WRITE, 0, 64 << 10);
OS.memory().writeLong(1024L, 0x1234567890ABCDEFL);
OS.unmap(address, 64 << 10);Read that sequence carefully, because it is the shape of everything this library enables. A channel is mapped with OS.map in READ_WRITE mode over a 64 kilobyte window, the returned address is a raw native address, and OS.memory().writeLong writes directly to an offset in that mapping with no object allocation and no garbage collection involvement. Then OS.unmap releases the window.
The JVM Access Methods section covers platform specific features of the JVM itself, which is the other half of the offering: low-level access to native memory, JVM internals and the OS.
The practical warning here is not about the syntax, it is about the semantics. Once you write past the end of a mapping, or read an address after unmapping it, the JVM cannot help you. There is no exception, no stack trace pointing at your code, and no safe fallback. That is what the caution in the summary is pointing at.
Closeable and reference counted resources, released without the garbage collector
Deterministic Resource Management is the feature most teams can actually use without writing a single raw pointer. Chronicle-Core provides components that can be closed or reference-counted, and released deterministically without waiting for garbage collection.
The Closeable Resources interface covers resources that are open when created and cannot be used once closed, which helps in preventing resource leaks. The shape of the contract is visible in the project's own test:
public class AbstractCloseableTest {
@Test
public void close() {
MyCloseable mc = new MyCloseable();
assertFalse(mc.isClosed());
assertEquals(0, mc.performClose);
mc.throwExceptionIfClosed();
mc.close();
assertTrue(mc.isClosed());
assertEquals(1, mc.performClose);
}
}The important method is throwExceptionIfClosed. A resource that has been closed is not merely in a bad state, it throws when used. That converts a use-after-close from a silent corruption into an exception you can catch, which is the difference between a bug you debug in an afternoon and one you debug in production for a month.
The reference counting variant extends the same idea to shared resources. A reference-counted resource can add reservations until it is closed:
public class AbstractReferenceCountedTest {
@Test
public void reserve() {
assertTrue(Jvm.isResourceTracing());
MyReferenceCounted rc = new MyReferenceCounted();
assertEquals(1, rc.refCount());
ReferenceOwner a = ReferenceOwner.temporary("a");
rc.reserve(a);
assertEquals(2, rc.refCount());
//...
}
}Note that the reference count starts at 1 before any reservation, and that reservations carry an owner, a ReferenceOwner in the example, created as temporary. Ownership semantics matter here, because the count going to zero is what triggers release and you need to know who is responsible for the last release. There is a resource tracing facility behind Jvm.isResourceTracing, which is how you find out which code is holding a reference when a leak investigation starts.
Thread safety checks turn a race condition into a stack trace
The library enables the use of thread safety checks for single-threaded components.
This is a smaller feature than the mapping calls, and it is arguably more useful per line of code. A component that is not thread safe, used from two threads, usually fails quietly: the value is wrong and the bug surfaces somewhere else, minutes or hours later. A thread safety check makes the wrong usage fail at the point of the wrong usage.
That is exactly the class of problem the rest of this library can cause. Once you have off-heap state shared between threads, a missing synchronisation is no longer a logic bug, it is a memory corruption bug, and the reference counting and closeable patterns above only help if each component can also tell you it is being used wrongly.
The repository layout suggests the thread safety checks are wired in deeply rather than being a decorator. There is a whole directory named assertions-enabled and another named assertions-disabled, which is how you get a check that behaves differently in development and production builds. The presence of a checked-exceptions directory at the top level suggests the same careful treatment of how failures are signalled.
The other listed areas sit in the same category of low-level utility rather than application feature. The library wraps up low-level access to system properties from a file, off-heap memory access, object pools, class local caching, and maths functions for casting types, rounding double and faster hashing. It also covers serializable lambdas and a high performance wide range histogram.
system.properties loads before your main method runs, and command line wins
The system properties from file feature is the first thing many adopters will actually use, and it is the least dangerous part of the library.
The Jvm class automatically loads system properties from a system.properties file if found in the current directory or parent directory. This feature aids in streamlining your command line. You can specify a different properties file with the -Dsystem.properties=my.properties command, and the file to load can be overridden on the command line the same way. The triggering is a static initialiser:
static {
Jvm.init();
}The precedence rule is stated explicitly and is the detail to remember: command line-specified system properties override those in the system.properties file. So a value set with -D on the command line always wins over the file, and the file is a default layer rather than a competing source of truth.
There is an implementation detail worth knowing about because it explains why this works reliably. The Jvm.java source shows how the JVM class is guaranteed to be initialized before the system property is read, for example with Jvm.getInteger or Jvm.getLong. Without that ordering, a property read during class initialisation could observe a half-configured state.
A number of relevant system properties are listed in the systemProperties.adoc document in the docs directory. That file is the reference for what else the library lets you configure, and it lives in the repository rather than only on a website, which matters when the default branch is ea and the website tracks the latest release.
ChronicleInit lets you run your own code before Chronicle reads a property
ChronicleInit is the initialization class that enables developers to run their own code at startup. This code can be executed before and/or after the execution of Chronicle's static initializers, which perform tasks such as system property loading.
That timing is the whole point of the mechanism. Chronicle static initialisers perform tasks such as loading system properties, so it is possible, for example, to override system properties using ChronicleInit. In other words, if you need a property value that depends on runtime logic rather than a file, this is the supported hook for computing it before the library reads it.
Two system properties drive it. The first is chronicle.init.runnable, a fully qualified class name that will be run before any system property is read by Chronicle code, allowing the class to set them to the desired values. The class should contain an empty static init() method that is called to trigger class load.
The second is chronicle.postinit.runnable, a fully qualified class name that will run only once after the Jvm initialisation static class. The class should contain an empty static postInit() method that is called to trigger it.
The design is deliberately minimal. An empty static method as the trigger is unusual compared with the usual ServiceLoader or reflection based mechanisms, and it has a practical benefit: the class gets loaded and initialised by the JVM as a side effect of the static method call, so there is no separate registration step and no configuration file to keep in sync. The cost is that both hooks are global rather than scoped to a component, so in a JVM with several Chronicle based libraries loaded, the ordering rules are the thing you have to reason about.
The repository also carries an AGENTS.md file at the top level, which suggests the project documents conventions for automated tooling contributors.
Building against Java 8 and Java 21, and the release cadence
The build story is short and the matrix matters. Chronicle-Core builds against Java 8 and Java 21 with the standard Maven command:
mvn clean installThe most recent runs completed successfully, and the project says the full output and warnings are in build-java8.log and build-java21.log in the repository root. That is a helpful convention, because a dual JDK build is where surprises live, and having the logs checked in means you can diff your own build against a known good one.
Release naming is calendar based, with the tags chronicle-core-2026.6, chronicle-core-2026.5, and chronicle-core-2026.4 published on 2026-07-24, 2026-06-11, and 2026-06-04 respectively. That cadence is frequent by any standard, and it also tells you the versioning is tied to the release date rather than to a semantic scheme, so you cannot assume a minor bump means a feature and a major bump means a break.
The last push to the repository was on 2026-09-22, so the work is current. The default branch being ea rather than master is the other fact to keep in mind, because if you depend on this library you are depending on a branch that is expected to change.
The Apache-2.0 licence makes embedding it in commercial products straightforward, which matters given the library's position as a dependency underneath other Chronicle projects. The practical upgrade cost is not the licence but the API surface, and it sits in a different directory in the repository, with a pom.xml at the root and the source under src.
Editorial conclusion
Chronicle-Core fits a Java engineer writing latency sensitive or allocation constrained code who needs off-heap access, deterministic resource release and system level primitives in one dependency rather than several. It does not fit an application developer who has no reason to leave the heap, and the project's own caution about misuse should be read as a warning about the whole API surface, not only the mapping calls. Before adopting it, read the OS Calls and JVM Access Methods sections and check the build matrix, because the library builds against both Java 8 and Java 21 and the system property plumbing differs between them.
Frequently asked questions
What does Chronicle-Core give a Java developer access to?
It provides access to operating system calls such as the process ID, the operating system check and the hostname, JVM access methods for platform specific features, memory mapped files, and off-heap memory access.
How do you build Chronicle-Core?
It builds against Java 8 and Java 21 with the standard Maven command mvn clean install, and the project keeps build-java8.log and build-java21.log in the repository root.
How does Chronicle-Core load system properties from a file?
The Jvm class automatically loads system properties from a system.properties file found in the current directory or a parent directory, and a different file can be selected with -Dsystem.properties=my.properties. Command line specified system properties override those in the file.
What does the ChronicleInit class do?
It lets you run your own code at startup, before and/or after the Chronicle static initializers. The chronicle.init.runnable property names a class with an empty static init() method run before any system property is read, and chronicle.postinit.runnable names a class with an empty static postInit() method run once after the Jvm initialization static class.
How does Chronicle-Core release resources without waiting for garbage collection?
It provides closeable resources that are open when created and cannot be used once closed, with throwExceptionIfClosed making misuse fail loudly, and reference counted resources that add reservations until closed and can be released deterministically.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/openhft-chronicle-core)Was this useful?