protobuf性能优于json:体积小(仅其1/3–1/5)、编解码快、强类型、兼容性好;json胜在可读、调试方便、跨语言支持成熟。

原生序列化(比如 Java 的 Serializable、Python 的 pickle、.NET 的 BinaryFormatter)本质上是语言运行时私有的数据封存机制,它不面向跨系统通信设计,因此在跨语言、性能和安全性三个关键维度上存在明显硬伤。
跨语言兼容性几乎为零
原生序列化格式由语言虚拟机或解释器内部定义,没有统一规范。Java 序列化字节流无法被 Python 识别,Go 的 gob 在 Rust 中完全不可读,C++ 手动二进制序列化更无标准可言。这意味着:
- 服务端用 Java 写,客户端用 JavaScript —— 原生序列化数据根本无法解析
- 微服务间若混用不同语言,强行传递原生字节会直接崩溃或静默失败
- 即使同语言不同版本(如 Java 8 ↔ Java 17),
serialVersionUID不匹配也会反序列化失败
性能表现常被高估,实际开销隐蔽
表面看“直接写内存”很快,但真实瓶颈不在序列化本身,而在后续环节:
- 反射式序列化(如 Java
Serializable)需遍历所有字段、检查访问权限、处理 transient/serialPersistentFields,比 Protobuf 的扁平二进制编码慢 3–5 倍 - 反序列化时动态重建对象图,触发大量 GC 和类加载,尤其嵌套深、引用多时延迟突增
- 无压缩、无字段跳过机制:哪怕只改一个字段,也要传输整个对象状态,网络带宽浪费严重
安全性风险集中且难以缓解
原生序列化本质是“执行式还原”,反序列化过程可能触发任意代码:
-
java.io.Serializable的readObject()可被恶意重写,成为反序列化漏洞入口(Log4j2 等重大漏洞均与此相关) - Python
pickle允许执行任意函数调用,官方明确警告“永远不要反序列化不可信数据” - 缺乏类型校验与字段白名单机制,攻击者可注入伪造类、篡改字段值、绕过业务逻辑校验
对比 JSON 与 Protobuf 的定位差异
JSON 和 Protobuf 都是**契约先行、语言中立、面向传输**的序列化方案:
- JSON 胜在可读、调试方便、浏览器直通,适合配置、开放 API、前端交互
- Protobuf 胜在体积小(通常只有 JSON 的 1/3–1/5)、编解码快(无文本解析开销)、强类型约束、天然支持字段增删兼容(靠编号而非名称)
- 二者都默认不执行代码、不依赖运行时环境、可通过 schema 工具链做静态校验,安全边界清晰
原生序列化只应在单语言、可信进程内短生命周期场景下谨慎使用(如 JVM 进程内缓存)。一旦涉及网络、存储、多语言协作,必须切换到 JSON、Protobuf 或 MessagePack 等标准化协议。











