How Fury Achieves 20‑200× Faster Java Serialization Than JDK, Hessian, and Kryo

Fury is a JIT‑compiled, multi‑language native serialization framework that fully implements JDK custom serialization, delivering 20‑200× speed improvements over JDK, Hessian, and Kryo, while preserving compatibility across Java, Python, Go, C++, and JavaScript, as demonstrated by detailed protocol analysis and performance benchmarks.

Alibaba Cloud Developer
Alibaba Cloud Developer
Alibaba Cloud Developer
How Fury Achieves 20‑200× Faster Java Serialization Than JDK, Hessian, and Kryo

Preface

Fury is a high‑performance, JIT‑based native serialization framework that supports Java, Python, Go, C++, JavaScript and provides fully automatic cross‑language object serialization with performance up to 20‑200× higher than other frameworks.

JDK Serialization Principle Analysis

The JDK uses ObjectOutputStream and ObjectInputStream. Users can customize serialization via methods such as writeObject, readObject, writeReplace, readResolve, etc. When these methods are present, the default JDK serializer cannot be bypassed, forcing developers to use the slow built‑in JDK serialization.

Typical JDK serialization flow:

Custom Serialization Methods

If an object defines writeReplace, the method is invoked first; the returned object may replace the original in the reference table. If the returned type still defines writeReplace, the process repeats. When writeReplace is absent, the serializer proceeds to field serialization, using either Externalizable or the default field traversal.

When writeObject is defined, it may call defaultWriteObject or implement custom logic. Compatibility across JDK versions is handled via putFields / writeFields. Example from ThreadLocalRandom:

private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
    java.io.ObjectOutputStream.PutField fields = s.putFields();
    fields.put("rnd", U.getLong(Thread.currentThread(), SEED));
    fields.put("initialized", true);
    s.writeFields();
}

Problems with Existing Frameworks

Hessian Issues

Hessian only supports writeReplace / readResolve. When writeReplace returns an object of the same type, a stack overflow occurs:

public static class CustomReplaceClass implements Serializable {
    Object writeReplace() { return new CustomReplaceClass(); }
    Object readResolve() { return new CustomReplaceClass(); }
}
Exception in thread "main" java.lang.StackOverflowError
    at ... WriteReplaceSerializer.writeReplace(...)
    ...

Hessian also ignores writeObject / readObject, causing data loss for many JDK classes.

Kryo Issues

Relies on JDK serialization for objects with custom methods, leading to severe performance degradation.

Produces large serialized payloads.

Fails to share reference tables for sub‑graphs, causing duplicate serialization or stack overflows.

Does not support parent‑child fields with the same name.

Other Framework Limitations

Jsonb does not support any JDK custom serialization methods.

Fst lacks forward/backward compatibility.

Fury Compatibility Implementation

Early Fury versions delegated to JDK serialization for custom methods, but since version 0.9.2 Fury provides a complete, JIT‑accelerated implementation of the entire JDK serialization protocol, achieving orders‑of‑magnitude speed gains.

ReplaceResolveSerializer

Implements the exact JDK replace/resolve behavior, handling cases where writeReplace returns a different type without causing stack overflows, and reduces serialized size by omitting redundant class metadata.

ObjectStreamSerializer

Fully supports JDK methods writeObject, readObject, writeReplace, readResolve, readObjectNoData, and registerValidation, ensuring 100% compatibility.

Serializer Initialization

Fury obtains a no‑arg constructor (or the first non‑serializable superclass constructor) and, for JDK 17+, may use Unsafe to bypass access restrictions.

Constructor constructor;
try {
    constructor = type.getConstructor();
    if (!constructor.isAccessible()) {
        constructor.setAccessible(true);
    }
} catch (Exception e) {
    constructor = (Constructor) ReflectionUtils.getObjectFieldValue(
        ObjectStreamClass.lookup(type), "cons");
}

It then builds a list of SlotsInfo objects representing each serializable class in the hierarchy, creating JIT‑compatible serializers for default field handling and custom method handling.

List<SlotsInfo> slotsInfoList = new ArrayList<>();
Class<?> end = type;
while (end != null && Serializable.class.isAssignableFrom(end)) {
    end = end.getSuperclass();
}
while (type != end) {
    slotsInfoList.add(new SlotsInfo(fury, type));
    type = type.getSuperclass();
}
Collections.reverse(slotsInfoList);
slotsInfos = slotsInfoList.toArray(new SlotsInfo[0]);

Serialization Execution

For each SlotsInfo, Fury either invokes the JIT serializer for default fields or calls the user‑defined writeObject method via a temporary FuryObjectOutputStream:

for (SlotsInfo slotsInfo : slotsInfos) {
    buffer.writeShort((short) slotsInfos.length);
    classResolver.writeClassInternal(buffer, slotsInfo.cls);
    Method writeObjectMethod = slotsInfo.writeObjectMethod;
    if (writeObjectMethod == null) {
        slotsInfo.slotsSerializer.write(buffer, value);
    } else {
        FuryObjectOutputStream objectOutputStream = slotsInfo.objectOutputStream;
        Object oldObject = objectOutputStream.targetObject;
        MemoryBuffer oldBuffer = objectOutputStream.buffer;
        try {
            objectOutputStream.targetObject = value;
            objectOutputStream.buffer = buffer;
            writeObjectMethod.invoke(value, objectOutputStream);
        } finally {
            objectOutputStream.targetObject = oldObject;
            objectOutputStream.buffer = oldBuffer;
        }
    }
}

Deserialization Execution

Fury creates the object using the appropriate constructor, reads the class hierarchy, and either invokes the JIT deserializer or the user‑defined readObject method. It also respects readObjectNoData, registerValidation, and readResolve callbacks.

Object obj = null;
if (constructor != null) {
    obj = constructor.newInstance();
} else {
    obj = Platform.newInstance(type);
}
int numClasses = buffer.readShort();
for (int i = 0; i < numClasses; i++) {
    Class<?> currentClass = classResolver.readClassInternal(buffer);
    SlotsInfo slotsInfo = slotsInfos[slotIndex++];
    while (currentClass != slotsInfo.cls) {
        Method readObjectNoData = slotsInfo.readObjectNoData;
        if (readObjectNoData != null) {
            readObjectNoData.invoke(obj);
        }
        slotsInfo = slotsInfos[slotIndex++];
    }
    Method readObjectMethod = slotsInfo.readObjectMethod;
    if (readObjectMethod == null) {
        slotsInfo.slotsSerializer.readAndSetFields(buffer, obj);
    } else {
        FuryObjectInputStream objectInputStream = slotsInfo.objectInputStream;
        // invoke readObject with FuryObjectInputStream
        readObjectMethod.invoke(obj, objectInputStream);
    }
}
for (ObjectInputValidation validation : callbacks.values()) {
    validation.validateObject();
}

Performance Comparison

After implementing full JDK compatibility, Fury never falls back to JDK serialization. Benchmarks show a 10× speed advantage over Kryo and a 3× advantage over Hessian for typical string‑heavy workloads.

Flame graphs confirm that JDK serialization stacks are completely eliminated:

Conclusion

Since version 0.9.2, Fury provides a uniquely 100% compatible and high‑performance alternative to JDK, Kryo, and Hessian serialization, enabling developers to abandon slow JDK serialization without sacrificing correctness.

Fury will be open‑sourced soon; interested parties can contact the author via email.

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.

JavaperformanceserializationJDKHessianFuryKryo
Alibaba Cloud Developer
Written by

Alibaba Cloud Developer

Alibaba's official tech channel, featuring all of its technology innovations.

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.