Kryo Documentation

repository·master·Indexed 27 days ago

https://github.com/esotericsoftware/kryo

Kryo is a fast and efficient binary object graph serialization framework for Java, designed for high speed, low size, and ease of use. It supports persisting objects to files and databases, transmitting them over networks, and performing deep or shallow object copying. The framework includes specialized IO classes like Output, Input, ByteBuffer, and Unsafe buffers, as well as support for variable length encoding and chunked streaming.

Tokens
11.8K
Snippets
29
Records
50
Agent score
42%

What's inside Kryo

  1. Handle cross-language interoperability

    master
    The default Kryo serializers assume that Java will be used for deserialization. They do not explicitly define a standardized format that is easily readable by other programming languages. If you require cross-language support, you may need to implement custom serializers using a standardized format.
  2. Quickstart: Serialize and deserialize an object with Kryo

    master

    Kryo provides a high-speed binary serialization framework. To perform a round-trip serialization:

    1. Instantiate a Kryo object.
    2. Register your classes using kryo.register(Class).
    3. Use Output to write the object to a stream.
    4. Use Input to read the object back from a stream.
    import com.esotericsoftware.kryo.Kryo;
    import com.esotericsoftware.kryo.io.Input;
    import com.esotericsoftware.kryo.io.Output;
    import java.io.*;
    
    public class HelloKryo {
       static public void main (String[] args) throws Exception {
          Kryo kryo = new Kryo();
          kryo.register(SomeClass.class);
    
          SomeClass object = new SomeClass();
          object.value = "Hello Kryo!";
    
          Output output = new Output(new FileOutputStream("file.bin"));
          kryo.writeObject(output, object);
          output.close();
    
          Input input = new Input(new FileInputStream("file.bin"));
          SomeClass object2 = kryo.readObject(input, SomeClass.class);
          input.close();   
       }
       static public class SomeClass {
          String value;
       }
    }
  3. Apply compression or encryption to serialized data

    master

    Since Kryo works with streams, you can easily wrap your OutputStream with compression (e.g., DeflaterOutputStream) or encryption to protect the entire serialized payload.

    OutputStream outputStream = new DeflaterOutputStream(new FileOutputStream("file.bin"));
    Output output = new Output(outputStream);
    Kryo kryo = new Kryo();
    kryo.writeObject(output, object);
    output.close();
  4. Manage class changes with forward and backward compatibility

    master

    Kryo provides generic serializers to handle changes to classes for long-term storage:

    • Forward compatibility: Reading bytes serialized by newer classes.
    • Backward compatibility: Reading bytes serialized by older classes.

    You can use Kryo's generic serializers or develop custom serializers (e.g., using an external schema) to manage these compatibility requirements.

  5. Use Chunked encoding for streaming large data

    master

    When the length of data is unknown ahead of time, OutputChunked and InputChunked allow you to write data in chunks. This avoids the need for a single massive buffer to determine the total length before writing.

    • OutputChunked: Extends Output. When the internal buffer is full, it flushes the chunk to the underlying OutputStream. Use endChunk() to mark the end of a set of chunks.
    • InputChunked: Extends Input. Use nextChunks() to advance to the next set of chunks.
    // Writing chunked data
    OutputStream outputStream = new FileOutputStream("file.bin");
    OutputChunked output = new OutputChunked(outputStream, 1024);
    // Write data to output...
    output.endChunk();
    // Write more data to output...
    output.endChunk();
    output.close();
    
    // Reading chunked data
    InputStream inputStream = new FileInputStream("file.bin");
    InputChunked input = new InputChunked(inputStream, 1024);
    // Read data from first set of chunks...
    input.nextChunks();
    // Read data from second set of chunks...
    input.nextChunks();
    input.close();
  6. Handle thread safety with ThreadLocal

    master

    Kryo is not thread safe. Each thread must use its own instance of Kryo, Input, and Output. In multithreaded environments, you can use ThreadLocal to manage these instances efficiently.

    static private final ThreadLocal<Kryo> kryos = new ThreadLocal<Kryo>() {
       protected Kryo initialValue() {
          Kryo kryo = new Kryo();
          // Configure the Kryo instance.
          return kryo;
       };
    };
    
    Kryo kryo = kryos.get();
  7. Limit deserialized size to prevent memory exhaustion

    master

    To protect against malicious or corrupt messages that declare massive sizes (e.g., billions of elements) to trigger large allocations, you should bound the allowed size when reading from an InputStream using setMaxArraySize.

    For Input instances backed by a byte array (no InputStream), this is guarded automatically. For Input instances reading from an InputStream, the default limit is Integer.MAX_VALUE. Set a limit suited to your application to throw a KryoException if a declared size exceeds the threshold.

    Input input = new Input(inputStream);
    input.setMaxArraySize(1024 * 1024); // reject any declared array/string/collection/map size above 1M elements
  8. Understand Kryo versioning and compatibility rules

    master

    Kryo uses specific versioning rules to signal breaking changes:

    1. Major Version: Increased if serialization compatibility is broken (data serialized with a previous version may not be deserializable with the new version).
    2. Minor Version: Increased if binary or source compatibility of the documented public API is broken.

    When upgrading Kryo, always check the release changelog for specific reports on serialization, binary, and source compatibility to ensure your application remains functional.

  9. Configure JMH parameters for Kryo benchmarks

    master

    Kryo benchmarks use JMH (Java Microbenchmark Harness). If no parameters are provided, the benchmarks run with development settings (-f 0 -wi 1 -i 1 -t 1 -w 1s -r 1s), which are fast but not suitable for production-grade results.

    Standard Parameters

    For reasonable, reliable results, use these parameters:

    -f 4 -wi 5 -i 3 -t 2 -w 2s -r 2s

    Filtering Benchmarks

    To run specific benchmark classes or individual methods within a class, append the names to your parameter list:

    • Specific Class: -f 4 -wi 5 -i 3 -t 2 -w 2s -r 2s FieldSerializerBenchmark
    • Specific Methods: -f 4 -wi 5 -i 3 -t 2 -w 2s -r 2s FieldSerializerBenchmark.field FieldSerializerBenchmark.tagged

    To see all available JMH parameters, run:

    java -cp "benchmarks/lib/*" org.openjdk.jmh.Main -h
  10. Install Kryo via Maven

    master

    Kryo provides two types of artifacts depending on whether you are building an application or a library.

    • For Applications: Use the default kryo artifact. This includes standard library dependencies.
    • For Libraries: Use the kryo5 artifact. This is a dependency-free, "versioned" jar designed to avoid dependency conflicts when multiple libraries use different major versions of Kryo.

    To use snapshots, you must also include the Sonatype snapshots repository in your pom.xml.

    <!-- For usage in an application: -->
    <dependency>
       <groupId>com.esotericsoftware</groupId>
       <artifactId>kryo</artifactId>
       <version>5.6.2</version>
    </dependency>
    
    <!-- For usage in a library that should be published: -->
    <dependency>
       <groupId>com.esotericsoftware.kryo</groupId>
       <artifactId>kryo5</artifactId>
       <version>5.6.2</version>
    </dependency>