介绍
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)的二进制值,无需包装。
依赖
<!-- Kryo 核心依赖 -->
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<version>5.5.0</version> <!-- 推荐使用最新稳定版 -->
</dependency>
例子
简单序列化/反序列化
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}
}
}
}
自定义序列化器
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
// 自定义序列化器
class UserSerializer extends Serializer<User> {
@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<User> 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 原生快数倍,支持复杂对象和循环引用,可自定义序列化逻辑。
- 最佳实践:
- 生产环境建议注册类并设置
setRegistrationRequired(true),提升性能和安全性。 - 处理循环引用时确保
setReferences(true)(默认开启)。 - 对特殊类型(如日期、集合)使用自定义序列化器优化性能。
- 生产环境建议注册类并设置
- 适用场景:Java 内部高性能序列化需求(大数据、游戏、缓存),跨语言场景需选 Protobuf/Avro。
简单来说,Kryo 是 Java 序列化的“性能王者”,是追求极致性能场景的首选。