Fundamentals 13 min read

Boost Java Serialization Performance with ChronicleWire: A Practical Guide

This article explains Java's built‑in serialization drawbacks, introduces the open‑source ChronicleWire library as a high‑performance alternative supporting multiple data formats, and provides step‑by‑step code examples for encoding, decoding, and compatibility handling in real‑world Java applications.

FunTester
FunTester
FunTester
Boost Java Serialization Performance with ChronicleWire: A Practical Guide

Background

Java serialization converts objects to a byte stream for storage or network transmission, but the default mechanism can be slow and memory‑intensive, especially for complex object graphs with circular references.

ChronicleWire Overview

ChronicleWire is an open‑source library originally built for ChronicleQueue and ChronicleMap. It abstracts the wire implementation so that objects only need to implement the net.openhft.chronicle.wire.Marshallable interface instead of java.io.Serializable. The library supports binary, YAML, JSON, raw binary, and CSV formats and allows format switching without code changes.

Encoding Formats and Compact Representation

ChronicleWire stores data in the smallest possible number of bytes. For integers it uses stop‑bit (variable‑length) encoding, where the highest bit of each byte indicates whether more bytes follow, dramatically reducing the byte count for small numbers.

Example: YAMLWire Serialization

import net.openhft.chronicle.bytes.Bytes;
import net.openhft.chronicle.core.pool.ClassAliasPool;
import net.openhft.chronicle.wire.Marshallable;
import net.openhft.chronicle.wire.Wire;
import net.openhft.chronicle.wire.YamlWire;

class WireDemo {
    static class Tester implements Marshallable {
        int age;
        String name;
        Tester(String name, int age) { this.name = name; this.age = age; }
    }
    public static void main(String... args) {
        ClassAliasPool.CLASS_ALIASES.addAlias(Tester.class);
        Wire wire = new YamlWire(Bytes.allocateElasticOnHeap());
        wire.getValueOut().object(new Tester("FunTester", 18));
        System.out.println(wire);
    }
}

Console output:

!Tester {
  number: 18,
  driver: FunTester
}

Switching to JSONWire with Type Information

Wire wire = new JSONWire(Bytes.allocateElasticOnHeap()).useTypes(true);

When useTypes(true) is enabled, the serialized JSON includes the Java type:

{"@Tester":{"age":18,"name":"FunTester"}}

Binary Wire Example

Wire wire = WireType.FIELDLESS_BINARY.apply(Bytes.allocateElasticOnHeap());
wire.getValueOut().object(new Tester("FunTester", 18));
System.out.println(wire.bytes().toHexString());

Hex dump:

00000000 b6 06 54 65 73 74 65 72 82 0c 00 00 00 a1 12 e9
00000010 46 75 6e 54 65 73 74 65 72

Deserialization from JSONWire

Wire wire = new JSONWire().useTypes(true);
wire.bytes().append("{\"@Tester\":{\"age\":18,\"name\":\"FunTester\"}}");
Object obj = wire.getValueIn().object();
System.out.println(obj.getClass().getName());
Tester t = (Tester) obj;
System.out.println(t.name);
System.out.println(t.age);

Console output:

com.funtest.queue.WireDemo$Tester
FunTester
18

Compatibility Handling

If a new field (e.g., int height) is added to the POJO, older data will deserialize with the new field defaulting to zero, preserving backward compatibility.

String Storage with Base64 Encoding

class FunText extends SelfDescribingMarshallable {
    @LongConversion(Base64LongConverter.class)
    long text;
    FunText(CharSequence text) { this.text = Base64LongConverter.INSTANCE.parse(text); }
    CharSequence text() { return Base64LongConverter.INSTANCE.append(new StringBuilder(), text); }
}

public static void main(String[] args) {
    ClassAliasPool.CLASS_ALIASES.addAlias(FunText.class);
    Wire wire = new BinaryWire(Bytes.allocateElasticOnHeap());
    wire.getValueOut().object(new FunText("FunTester"));
    System.out.println("Serialized: " + wire.bytes().toHexString());
    System.out.println("Deserialized: " + wire.getValueIn().object());
}

Sample output shows a compact 8‑byte representation for the string and successful deserialization back to the original object.

Conclusion

ChronicleWire provides a flexible, high‑performance alternative to Java's native serialization, allowing developers to choose the most suitable format (binary, YAML, JSON, etc.) without modifying application code, making it ideal for large‑scale or low‑latency Java applications.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaperformanceserializationData FormatsBinaryChronicleWire
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.