Java Kryo序列化 作者:马育民 • 2025-11-28 14:15 • 阅读:10001 # 介绍 Kryo 是一个**快速、高效的 Java 序列化框架**,专为性能优化设计,比 JDK 原生序列化快 5-10 倍,生成的二进制数据体积更小。它支持**对象图序列化**(包括循环引用)、**类注册**(提升性能)和**自定义序列化逻辑**,广泛应用于游戏、大数据、分布式缓存等高性能场景。 ### 适用场景 - **大数据计算**:Spark/Flink 分布式计算中的对象序列化(替代 JDK 原生提升性能)。 - **游戏开发**:游戏服务器间的对象传输(高性能、小体积)。 - **分布式缓存**:Redis/Memcached 存储 Java 对象(比 JSON 更高效)。 - **RPC 框架**:高性能 RPC 通信(如 KryoNet)。 ### 核心特性 - **高性能**:基于字节码生成和优化的序列化算法,速度远超 JDK 原生。 - **体积小**:生成的二进制数据比 JDK 序列化小 30%-50%。 - **支持复杂对象**:处理循环引用、深对象图、集合、枚举等复杂结构。 - **类注册**:可选的类注册机制(通过整数 ID 替代类名),进一步提升性能和减小体积。 - **可扩展性**:支持自定义序列化器(Serializer),适配特殊类型。 - **兼容性**:支持跨 JVM 版本序列化/反序列化(需注意类结构兼容性)。 ### 底层实现原理 Kryo 的高性能源于以下核心设计: - **字节码生成**:通过动态生成字节码(而非反射)序列化对象,减少反射开销。 - **类注册机制**:将类映射为整数 ID,序列化时仅存储 ID(而非完整类名),减小数据体积。 - **对象引用跟踪**:通过引用表处理循环引用,避免栈溢出和重复序列化。 - **优化的基本类型处理**:直接写入基本类型(如 int、long)的二进制值,无需包装。 # 依赖 ``` com.esotericsoftware kryo 5.5.0 ``` # 例子 ### 简单序列化/反序列化 ```java import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output; import java.io.FileInputStream; import java.io.FileOutputStream; // 自定义类(无需实现 Serializable 接口) class User { private String name; private int age; private transient String password; // transient 字段默认不序列化 public User(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "User{name='" + name + "', age=" + age + "}"; } } public class KryoBasicDemo { public static void main(String[] args) throws Exception { // 1. 创建 Kryo 实例 Kryo kryo = new Kryo(); kryo.register(User.class); // 注册类(可选,提升性能) // 2. 序列化对象到文件 try (Output output = new Output(new FileOutputStream("user.kryo"))) { User user = new User("张三", 25); kryo.writeObject(output, user); } // 3. 从文件反序列化 try (Input input = new Input(new FileInputStream("user.kryo"))) { User deserializedUser = kryo.readObject(input, User.class); System.out.println(deserializedUser); // 输出 User{name='张三', age=25} } } } ``` ### 处理循环引用 ```java class Node { String value; Node next; // 循环引用 public Node(String value) { this.value = value; } } public class KryoCycleDemo { public static void main(String[] args) { Kryo kryo = new Kryo(); kryo.register(Node.class); kryo.setReferences(true); // 启用引用跟踪(默认开启) // 创建循环引用对象 Node node1 = new Node("A"); Node node2 = new Node("B"); node1.next = node2; node2.next = node1; // 循环引用 // 序列化/反序列化(无栈溢出) Output output = new Output(1024); kryo.writeObject(output, node1); Input input = new Input(output.getBuffer()); Node deserializedNode = kryo.readObject(input, Node.class); System.out.println(deserializedNode.next.next.value); // 输出 A(循环引用保留) } } ``` ### 自定义序列化器 ```java import com.esotericsoftware.kryo.Serializer; import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output; // 自定义序列化器 class UserSerializer extends Serializer { @Override public void write(Kryo kryo, Output output, User user) { output.writeString(user.name); output.writeInt(user.age * 2); // 加密年龄 } @Override public User read(Kryo kryo, Input input, Class type) { String name = input.readString(); int age = input.readInt() / 2; // 解密年龄 return new User(name, age); } } public class KryoCustomSerializerDemo { public static void main(String[] args) { Kryo kryo = new Kryo(); kryo.register(User.class, new UserSerializer()); // 注册自定义序列化器 Output output = new Output(1024); kryo.writeObject(output, new User("李四", 30)); Input input = new Input(output.getBuffer()); User user = kryo.readObject(input, User.class); System.out.println(user); // 输出 User{name='李四', age=30} } } ``` # 关键配置与优化 | 配置项 | 作用 | |-----------------------|----------------------------------------------------------------------| | `kryo.register(Class)` | 注册类,用整数 ID 替代类名,提升性能和减小体积。| | `kryo.setReferences(true)` | 启用引用跟踪,处理循环引用(默认开启)。| | `kryo.setRegistrationRequired(true)` | 强制类注册(避免未注册类的性能损耗,推荐生产环境使用)。| | `kryo.addDefaultSerializer(Class, Serializer)` | 为指定类设置默认序列化器。| # 与其他序列化方案对比 | 特性 | Kryo | JDK 原生 | Protobuf | |---------------------|---------------|---------------|---------------| | 速度 | 极快 | 慢 | 快 | | 体积 | 小 | 大 | 极小 | | 跨语言 | 否(仅 Java) | 否 | 是 | | 循环引用支持 | 是 | 是 | 否 | | 类注册 | 支持(可选) | 不支持 | 支持(必须) | # 总结 - **核心定位**:Kryo 是 Java 专用的高性能序列化框架,专注于速度和体积优化。 - **核心优势**:比 JDK 原生快数倍,支持复杂对象和循环引用,可自定义序列化逻辑。 - **最佳实践**: 1. 生产环境建议**注册类**并设置 `setRegistrationRequired(true)`,提升性能和安全性。 2. 处理循环引用时确保 `setReferences(true)`(默认开启)。 3. 对特殊类型(如日期、集合)使用自定义序列化器优化性能。 - **适用场景**:Java 内部高性能序列化需求(大数据、游戏、缓存),跨语言场景需选 Protobuf/Avro。 简单来说,Kryo 是 Java 序列化的“性能王者”,是追求极致性能场景的首选。 原文出处:http://malaoshi.top/show_1GW2JE5OXegc.html