{"id":19765860,"url":"https://github.com/openhft/chronicle-core","last_synced_at":"2026-01-28T22:01:55.749Z","repository":{"id":27773311,"uuid":"31261793","full_name":"OpenHFT/Chronicle-Core","owner":"OpenHFT","description":"Low level access to native memory, JVM and OS.","archived":false,"fork":false,"pushed_at":"2026-01-26T12:19:02.000Z","size":8089,"stargazers_count":623,"open_issues_count":12,"forks_count":134,"subscribers_count":45,"default_branch":"ea","last_synced_at":"2026-01-27T01:46:52.047Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenHFT.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2015-02-24T13:42:22.000Z","updated_at":"2026-01-26T12:19:07.000Z","dependencies_parsed_at":"2023-10-11T16:24:36.569Z","dependency_job_id":"ddaf40d3-781b-45a0-95f9-02e5200ea492","html_url":"https://github.com/OpenHFT/Chronicle-Core","commit_stats":null,"previous_names":[],"tags_count":528,"template":false,"template_full_name":null,"purl":"pkg:github/OpenHFT/Chronicle-Core","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHFT%2FChronicle-Core","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHFT%2FChronicle-Core/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHFT%2FChronicle-Core/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHFT%2FChronicle-Core/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenHFT","download_url":"https://codeload.github.com/OpenHFT/Chronicle-Core/tar.gz/refs/heads/ea","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHFT%2FChronicle-Core/sbom","scorecard":{"id":105312,"data":{"date":"2025-08-11","repo":{"name":"github.com/OpenHFT/Chronicle-Core","commit":"655bef412e78a19621250cb8661bd3851643f68d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":6.5,"checks":[{"name":"Code-Review","score":3,"reason":"Found 9/30 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":10,"reason":"25 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":10,"reason":"SAST tool detected","details":["Info: SAST configuration detected: Sonar","Warn: 8 commits out of 9 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-15T10:59:09.420Z","repository_id":27773311,"created_at":"2025-08-15T10:59:09.420Z","updated_at":"2025-08-15T10:59:09.420Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28853195,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-28T15:15:36.453Z","status":"ssl_error","status_checked_at":"2026-01-28T15:15:13.020Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T04:19:44.938Z","updated_at":"2026-01-28T22:01:55.735Z","avatar_url":"https://github.com/OpenHFT.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"= Chronicle-Core: An Advanced Low-Level Library\nChronicle Software\n:css-signature: demo\n:toc: macro\n:toclevels: 2\n:icons: font\n:lang: en-GB\n:sectnums:\n:source-highlighter: rouge\n\nimage:https://maven-badges.herokuapp.com/maven-central/net.openhft/chronicle-core/badge.svg[caption=\"\",link=https://maven-badges.herokuapp.com/maven-central/net.openhft/chronicle-core]\nimage:https://javadoc.io/badge2/net.openhft/chronicle-core/javadoc.svg[link=\"https://www.javadoc.io/doc/net.openhft/chronicle-core/latest/index.html\"]\n// image:https://javadoc-badge.appspot.com/net.openhft/chronicle-wire.svg?label=javadoc[JavaDoc, link=https://www.javadoc.io/doc/net.openhft/chronicle-core]\nimage:https://img.shields.io/github/license/OpenHFT/Chronicle-Core[GitHub]\nimage:https://img.shields.io/badge/release%20notes-subscribe-brightgreen[link=\"https://chronicle.software/release-notes/\"]\nimage:https://sonarcloud.io/api/project_badges/measure?project=OpenHFT_Chronicle-Core\u0026metric=alert_status[link=\"https://sonarcloud.io/dashboard?id=OpenHFT_Chronicle-Core\"]\n\nimage::images/Core_line.png[width=20%]\n\ntoc::[]\n\n== Build and test status\n\nChronicle-Core builds against Java 8 and Java 21 with the standard Maven command:\n\n[source,bash]\n----\nmvn clean install\n----\n\nThe most recent runs completed successfully; see `build-java8.log` and `build-java21.log` in the repository root for full output and warnings.\n\n== About Chronicle-Core\n\nChronicle-Core is an advanced low-level library that equips developers with powerful tools to interact with the operating system, manage memory, handle resources, and more.\nHowever, it should be used with caution due to its low-level operations which, if misused, can lead to complex issues.\n\nHere is a summary of the library's key features:\n\n*Operating System Calls:* Chronicle-Core provides access to various system calls such as retrieving the process ID, checking the operating system, and obtaining the hostname, among others.\n\n[source,java]\n----\nint processId = OS.getProcessId();\nboolean isWindows = OS.isWindows();\nString hostname = OS.getHostName();\n----\n\nSee the section on \u003c\u003cos-calls,OS Calls\u003e\u003e\n\n*JVM Access Methods:* To access platform specific features of the JVM.\n\nSee the section on \u003c\u003cjvm-access-methods,JVM Access Methods\u003e\u003e\n\n*Memory Mapped Files:* The library offers an interface for managing memory mapped files, which is useful for high-performance I/O operations.\n\n[source,java]\n----\nFileChannel fc = new CleaningRandomAccessFile(fileName, \"rw\").getChannel();\nlong address = OS.map(fc, MapMode.READ_WRITE, 0, 64 \u003c\u003c 10);\nOS.memory().writeLong(1024L, 0x1234567890ABCDEFL);\nOS.unmap(address, 64 \u003c\u003c 10);\n----\n\n*Deterministic Resource Management:* Chronicle-Core features components that can be closed or reference-counted, and released deterministically without waiting for garbage collection.\n\n*Closeable Resources:* Chronicle-Core provides an interface for managing closeable resources, which are open when created and can't be used once closed.\nThis helps in preventing resource leaks.\n\n[source,java]\n----\npublic class AbstractCloseableTest {\n    @Test\n    public void close() {\n        MyCloseable mc = new MyCloseable();\n        assertFalse(mc.isClosed());\n        assertEquals(0, mc.performClose);\n        mc.throwExceptionIfClosed();\n        mc.close();\n        assertTrue(mc.isClosed());\n        assertEquals(1, mc.performClose);\n    }\n}\n----\n\n*Resource Reference Counting:* The library enables the use of reference counting for deterministic resource release.\nA reference-counted resource can add reservations until it's closed.\n\n[source,java]\n----\npublic class AbstractReferenceCountedTest {\n    @Test\n    public void reserve() {\n        assertTrue(Jvm.isResourceTracing());\n        MyReferenceCounted rc = new MyReferenceCounted();\n        assertEquals(1, rc.refCount());\n        ReferenceOwner a = ReferenceOwner.temporary(\"a\");\n        rc.reserve(a);\n        assertEquals(2, rc.refCount());\n        //...\n    }\n}\n----\n\nSee the section on \u003c\u003cresource-reference-counting,Resource Reference Counting\u003e\u003e\n\n*Thread safety checks:* The library enables the use of thread safety checks for single-threaded components.\nSee the section on \u003c\u003cthread-safety-checks,Thread Safety Checks\u003e\u003e\n\nThis library also wraps up low level access to\n\n* \u003c\u003csystem-properties-from-file,System properties from a file\u003e\u003e\n* \u003c\u003coff-heap-memory-access,Off Heap Memory Access\u003e\u003e\n* \u003c\u003cobject-pools,Object Pools\u003e\u003e\n* \u003c\u003cclass-local-caching,Class Local Caching\u003e\u003e\n* \u003c\u003cmaths-functions,Maths Functions\u003e\u003e for casting types, rounding double, faster hashing.\n* \u003c\u003cserializable-lambdas,Serializable Lambdas\u003e\u003e\n* \u003c\u003chistogram,Histogram\u003e\u003e A high performance wide range histogram.\n\n== System properties from file\n\nChronicle-Core's `Jvm` class automatically loads system properties from a `system.properties` file if found in the current directory or parent directory.\nThis feature aids in streamlining your command line.\nYou can specify a different properties file with the `-Dsystem.properties=my.properties` command.\n\n[source,java]\n----\nstatic {\n    Jvm.init();\n}\n----\n\nThe choice of file to load can be overridden on the command line with `-Dsystem.properties=my.properties`\n\nIn link:https://github.com/OpenHFT/Chronicle-Core/blob/ea/src/main/java/net/openhft/chronicle/core/Jvm.java[Jvm.java] it can be seen how to guarantee that JVM class is initialized before the system property is read.\nFor example with Jvm.getInteger or Jvm.getLong.\n\nA number of relevant system properties are listed in link:docs/systemProperties.adoc[systemProperties.adoc].\n\nNOTE: Command line-specified system properties override those in the `system.properties` file.\n\n== Chronicle-Core Initialization\n\nChronicle-Core offers an initialization class, link:https://github.com/OpenHFT/Chronicle-Core/blob/ea/src/main/java/net/openhft/chronicle/core/ChronicleInit.java[`ChronicleInit`], that enables developers to run their own code at startup.\nThis code can be executed before and/or after the execution of Chronicle's static initializers, which perform tasks such as system property loading.\n\n`ChronicleInit` allows the developer to hook in their own code to be run at startup before and/or after the Chronicle static initialisers are run.\nChronicle static initialisers perform tasks such as loading system properties, so it is possible, for example, to override system properties using `ChronicleInit`.\nTo this end, `ChronicleInit` introduces the following system properties:\n\n. \"_chronicle.init.runnable_\"\n+\nThis system property specifies 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.\nThe class should contain an empty static `init()` method that is called to trigger class load.\n\n. \"_chronicle.postinit.runnable_\"\n+\nThis system property specifies a fully qualified class name that will run only once after the Jvm initialisation static class.\nThe class should contain an empty static `postInit()` method that is called to trigger class load.\n\nThe alternative way to using the above system properties is to implement the `ChronicleInitRunnable` interface whose implementing classes may be listed in the `META-INF/services/net.openhft.chronicle.core.ChronicleInitRunnable` file in any JAR in classpath to be discovered via `ServiceLoader` JVM facility.\nIt can provide both init and post-init functionalities by implementing the `ChronicleInitRunnableRunnable.run()` and `ChronicleInitRunnable.postInit()` methods.\n\n== Off Heap Memory Access\n\nThis allows you to access native memory using primitives and some thread safe operations.\n\n[source,java]\n----\nMemory memory = OS.memory();\nlong address = memory.allocate(1024);\ntry {\n    memory.writeInt(address, 1);\n    assert memory.readInt(address) == 1;\n    final boolean swapped = memory.compareAndSwapInt(address, 1, 2);\n    assert swapped;\n    assert memory.readInt(address) == 2;\n} finally {\n    memory.freeMemory(address, 1024);\n}\n----\n\n== JVM Access Methods\n\nCheck the JVM is running in debug mode\n\n[source,java]\n----\nif (Jvm.isDebug()) {\n   // running in debug.\n----\n\nRethrow a checked exception as an unchecked one.\n\n[source,java]\n----\ntry {\n    // IO operation\n} catch (IOException ioe) {\n    throw Jvm.rethrow(ioe);\n}\n----\n\nGet a Field for a Class by name\n\n[source,java]\n----\nField theUnsafe = Jvm.getField(Unsafe.class, \"theUnsafe\");\nUnsafe unsafe = (Unsafe) theUnsafe.get(null);\n----\n\n== OS Calls\n\nAccess to system calls\n\n[source,java]\n----\nint processId = OS.getProcessId();\nint maxProcessId = OS.getMaxProcessId();\nint pageSize = OS.getPageSize();\nboolean isWindows = OS.isWindows();\nboolean is64bit = OS.is64Bit();\nString hostname = OS.getHostName();\nString username = OS.getUserName();\nString targetDir = OS.getTarget(); // location the target directory during builds\n----\n\nMemory mapped files\n\n[source,java]\n----\nFileChannel fc = new CleaningRandomAccessFile(fileName, \"rw\").getChannel();\n// map in 64 KiB\nlong address = OS.map(fc, MapMode.READ_WRITE, 0, 64 \u003c\u003c 10);\n// use address\nOS.memory().writeLong(1024L, 0x1234567890ABCDEFL);\n// unmap memory region\nOS.unmap(address, 64 \u003c\u003c 10);\n----\n\n== Deterministic Resource Management\n\nComponent which are closeable or reference counted can be released deterministically without waiting for a GC.\n\n=== Closeable Resources\n\nA `Closeable` resources has a simple lifecycle.\nIt is open when created, and cannot be used once closed.\n\n[source,Java]\n----\npublic class AbstractCloseableTest {\n\n    @Test\n    public void close() {\n        MyCloseable mc = new MyCloseable();\n        assertFalse(mc.isClosed());\n        assertEquals(0, mc.performClose);\n\n        mc.throwExceptionIfClosed();\n\n        mc.close();\n        assertTrue(mc.isClosed());\n        assertEquals(1, mc.performClose);\n\n        mc.close();\n        assertTrue(mc.isClosed());\n        assertEquals(1, mc.performClose);\n    }\n\n    @Test(expected = IllegalStateException.class)\n    public void throwExceptionIfClosed() {\n        MyCloseable mc = new MyCloseable();\n        mc.close();\n        mc.throwExceptionIfClosed();\n\n }\n\n    @Test\n    public void warnAndCloseIfNotClosed() {\n        Map\u003cExceptionKey, Integer\u003e map = Jvm.recordExceptions();\n        MyCloseable mc = new MyCloseable();\n        mc.warnAndCloseIfNotClosed();\n        Jvm.resetExceptionHandlers();\n        assertEquals(\"Discarded without closing\\n\" +\n                        \"java.lang.IllegalStateException: net.openhft.chronicle.core.StackTrace: Created Here\",\n                map.keySet().stream()\n                        .map(e -\u003e e.message + \"\\n\" + e.throwable)\n                        .collect(Collectors.joining(\", \")));\n    }\n\n    static class MyCloseable extends AbstractCloseable {\n        int performClose;\n\n        @Override\n        protected void performClose() {\n            performClose++;\n        }\n    }\n}\n----\n\n=== Resource Reference Counting\n\nUse reference counting to deterministically release resources.\n\nA reference counted resource can add reservations until closed.\n\n[source,Java]\n----\npublic class AbstractReferenceCountedTest {\n\n    @Test\n    public void reserve() {\n        assertTrue(Jvm.isResourceTracing());\n        MyReferenceCounted rc = new MyReferenceCounted();\n        assertEquals(1, rc.refCount());\n\n        ReferenceOwner a = ReferenceOwner.temporary(\"a\");\n        rc.reserve(a);\n        assertEquals(2, rc.refCount());\n\n        ReferenceOwner b = ReferenceOwner.temporary(\"b\");\n        rc.reserve(b);\n        assertEquals(3, rc.refCount());\n\n        try {\n            rc.reserve(a);\n            fail();\n        } catch (IllegalStateException ignored) {\n        }\n        assertEquals(3, rc.refCount());\n\n        rc.release(b);\n        assertEquals(2, rc.refCount());\n\n        rc.release(a);\n        assertEquals(1, rc.refCount());\n        assertEquals(0, rc.performRelease);\n\n        rc.releaseLast();\n        assertEquals(0, rc.refCount());\n        assertEquals(1, rc.performRelease);\n    }\n\n    @Test\n    public void reserveWhenClosed() {\n        MyReferenceCounted rc = new MyReferenceCounted();\n        assertEquals(1, rc.refCount());\n\n        ReferenceOwner a = ReferenceOwner.temporary(\"a\");\n        rc.reserve(a);\n        assertEquals(2, rc.refCount());\n\n        assertFalse(rc.isClosed());\n\n        rc.closeable.close();\n\n        assertEquals(2, rc.refCount());\n        assertTrue(rc.isClosed());\n\n        ReferenceOwner b = ReferenceOwner.temporary(\"b\");\n        try {\n            rc.reserve(b);\n            fail();\n        } catch (IllegalStateException ignored) {\n        }\n        assertEquals(2, rc.refCount());\n\n        assertFalse(rc.tryReserve(b));\n        assertEquals(2, rc.refCount());\n\n        rc.release(a);\n        assertEquals(1, rc.refCount());\n        assertEquals(0, rc.performRelease);\n\n        rc.throwExceptionIfReleased();\n\n        rc.releaseLast();\n        assertEquals(0, rc.refCount());\n        assertEquals(1, rc.performRelease);\n\n        rc.throwExceptionBadResourceOwner();\n        try {\n            rc.throwExceptionIfClosed();\n            fail();\n        } catch (IllegalStateException ignored) {\n        }\n        try {\n            rc.throwExceptionIfReleased();\n            fail();\n        } catch (IllegalStateException ignored) {\n        }\n    }\n\n    @Test\n    public void throwExceptionBadResourceOwner() {\n        MyReferenceCounted rc = new MyReferenceCounted();\n        MyReferenceCounted rc2 = new MyReferenceCounted();\n        rc.reserve(rc2);\n        rc.throwExceptionBadResourceOwner();\n\n        rc2.closeable.close();\n        try {\n            rc.throwExceptionBadResourceOwner();\n            fail();\n        } catch (IllegalStateException ignored) {\n        }\n        rc.release(rc2);\n        rc.releaseLast();\n    }\n\n    @Test\n    public void throwExceptionIfClosed() {\n        MyReferenceCounted rc = new MyReferenceCounted();\n        rc.throwExceptionIfClosed();\n\n        rc.closeable.close();\n        try {\n            rc.throwExceptionIfClosed();\n\n           fail();\n        } catch (IllegalStateException ignored) {\n\n        }\n    }\n\n    static class MyReferenceCounted extends AbstractReferenceCounted {\n        final AbstractCloseable closeable;\n        int performRelease;\n\n        public MyReferenceCounted() {\n            this(new AbstractCloseableTest.MyCloseable());\n        }\n\n        public MyReferenceCounted(AbstractCloseable abstractCloseable) {\n            super(abstractCloseable);\n            closeable = abstractCloseable;\n        }\n\n        @Override\n        protected void performRelease() {\n            performRelease++;\n        }\n    }\n}\n----\n\n[source,java]\n----\nMappedFile mf = MappedFile.mappedFile(tmp, chunkSize, 0);\nMappedBytesStore bs = mf.acquireByteStore(chunkSize + (1 \u003c\u003c 10));\n\nassertEquals(2, mf.refCount());\nassertEquals(3, bs.refCount());\nassertEquals(\"refCount: 2, 0, 3\", mf.referenceCounts());\n\nmf.close();\nassertEquals(2, bs.refCount());\nassertEquals(\"refCount: 1, 0, 2\", mf.referenceCounts());\nbs2.releaseLast();\nassertEquals(1, mf.refCount());\nassertEquals(1, bs.refCount());\nbs.releaseLast();\nassertEquals(0, bs.refCount());\nassertEquals(0, mf.refCount());\nassertEquals(\"refCount: 0, 0, 0\", mf.referenceCounts());\n----\n\n=== Releasing Resources\n\nReleasing resources can be managed by starting the `BACKGROUND_RESOURCE_RELEASER` thread or alternatively it can be managed in a user defined thread.\nTo start the `BACKGROUND_RESOURCE_RELEASER` thread, both system properties `background.releaser` and `background.releaser.thread` should be set to `true`.\nIn this condition, the thread starts as a daemon thread and invokes `BackgroundResourceReleaser.runReleaseResources()`.\n\nIf only `background.releaser.thread` is set to `false`, resources will still be queued for releasing, but they need to be released explicitly by calling `BackgroundResourceReleaser.releasePendingResources()`.\n\nIf `background.releaser` is set to `false` regardless of `background.releaser.thread`, resources are not queued for release and release will be done synchronously (by calling the relevant close() function).\n\nCalling `BackgroundResourceReleaser.stop()` releases pending resources and then stops the `BACKGROUND_RESOURCE_RELEASER` thread.\nTo make sure the shutdown hook does not prevent classes from unloading, deregister the shutdown hook by calling `PriorityHook.clear()`.\n\n.Resource Release Configurations\n[%header,cols=3]\n|===\n| `background.releaser.thread` | `background.releaser` | Release Behaviour\n| `true` | `true` | Resources are queued and then released in the `BACKGROUND_RESOURCE_RELEASER` thread.\n| `false` | `true` | Rresources are queued but should be released in a user thread by calling `BackgroundResourceReleaser.releasePendingResources()`.\n| X | `false` | Resources are not queued and are released synchronously.\n|===\n\n== Thread Safety Checks\n\nClasses that are designed for single-threaded use can implement `net.openhft.chronicle.core.io.SingleThreadedChecked`.\nThere are a number of implementations of this in Chronicle-Core, including `net.openhft.chronicle.core.io.AbstractCloseable`, and many Chronicle library classes extend this class.\nWhen the user calls a method which _must_ be called single-threaded, these methods call a private method to check that `Thread.currentThread()` is the same as the first thread that used the object, and throws an exception if not.\n`AbstractCloseable` also provides very helpful functionality (if resource tracing is on) to keep track of the stack trace of where it was used first by the use-by thread - this provides invaluable when diagnosing unexpected sharing of an object between threads.\n\nThread safety checking can be turned off with the system property `disable.single.threaded.check`, once the application is thoroughly tested.\n\nAn object can be handed-off between threads by calling `singleThreadedCheckReset`.\n\n=== Thread safety patterns\n\nSome patterns which are commonly used in Chronicle's libraries are below.\n\n==== Initialise in one thread, use in another\n\nIf using an object which is single-threaded, a common pattern is to construct and initialise your object on the main thread before handing it off to an event loop or worker thread.\nCall `singleThreadedCheckReset` after initialisation.\n\n[source,java]\n----\n// in the Main thread\nChronicleQueue q = createMyQueue();\nExcerptTailer tailer = q.createTailer().toEnd(); // toEnd() checks thread safety and thus initialises the used-by thread\ntailer.singleThreadedCheckReset();\n// now use the tailer in an event loop\n----\n\n==== Reset in constructor\n\nIf writing an object to use `net.openhft.chronicle.core.io.SingleThreadedChecked` then a common pattern (and a variant of the above) is to call `singleThreadedCheckReset` at the end of the constructor e.g. from Chronicle Queue:\n\n[source,java]\n----\npublic ExcerptTailer createTailer(String id) {\n    ///\n    final StoreTailer storeTailer = new StoreTailer(this, pool, indexUpdater); // initialises state and sets the used-by thread\n    ///\n    storeTailer.singleThreadedCheckReset();\n    return storeTailer;\n}\n----\n\n==== Delegate through SingleThreadedCheck methods\n\nIf implementing `SingleThreadedCheck` then any methods should also delegate to any contained `SingleThreadedCheck`\nobjects i.e.\n\n[source,java]\n----\n@Override\npublic void singleThreadedCheckReset() {\n    // perform my reset\n    ///\n    // call singleThreadedCheckReset on any single-threaded fields\n    this.bytes.singleThreadedCheckReset();\n}\n----\n\n== Object Pooling\n\nChronicle-Core provides object pooling for strings and enums, allowing you to convert a `CharSequence` into a `String` of a specific `Enum` type efficiently.\n\n[source,java]\n----\nBytes\u003c?\u003e b = Bytes.from(\"Hello World\");\nb.readSkip(6);\n\nStringInterner si = new StringInterner(128);\nString s = si.intern(b);\nString s2 = si.intern(b);\nassertEquals(\"World\", s);\nassertSame(s, s2);\n----\n\n== Class Local Caching\n\nAdd caching of a data structure for each class using a lambda\n\n[source,java]\n----\npublic static final ClassLocal\u003cEnumInterner\u003e ENUM_INTERNER = \n        ClassLocal.withInitial(c -\u003e new EnumInterner\u003c\u003e(c));\n\nE enumValue = ENUM_INTERNER.get(enumClass).intern(stringBuilder);\n----\n\n== Maths Functions\n\nMaths functions to support rounds\n\n[source,java]\n----\ndouble a = 0.1;\ndouble b = 0.3;\ndouble c= Maths.round2(b - a); // 0.2 rounded to 2 decimal places\n----\n\nChecking type conversions\n\n[source,java]\n----\nint i = Maths.toInt32(longValue);\n----\n\n== Serializable Lambdas\n\nThere is a number of FunctionalInterfaces you can utilise as method arguments.\nThis allows implicitly making a lambda Serializable.\n\n[source,java]\n----\n// in KeyedVisitable\ndefault \u003cR\u003e R applyToKey(K key, @NotNull SerializableFunction\u003cE, R\u003e function) {\n\n// in code\n\nString fullename = map.applyToKey(\"u:123223\", u -\u003e u.getFullName());\n----\n\n== Histogram\n\nA high dynamic range histogram with tunable accuracy.\n\n[source,java]\n----\nHistogram h = new Histogram(32, 4);\nlong start = instance.ticks(), prev = start;\nfor (int i = 0; i \u003c= 1000_000_000; i++) {\n    long now = instance.ticks();\n    long time = now - prev;\n    h.sample(time);\n    prev = now;\n}\nSystem.out.println(h.toLongMicrosFormat(instance::toMicros));\n----\n\n== JLBH\n\nJLBH has moved home and now lives in its own project, see https://github.com/OpenHFT/JLBH[JLBH].\n\n== Loop Block Monitor tool\n\nThe tool to summarise the thread stack traces is here.\n\n`net.openhft.chronicle.core.threads.MonitorProfileAnalyserMain`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenhft%2Fchronicle-core","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenhft%2Fchronicle-core","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenhft%2Fchronicle-core/lists"}