Jackson,fastjson Gson比较

 本篇文章只是在理论上讨论jackson fastjson 以及Gson 之间的比较,不涉及代码测试,写这篇文章主要是看到了一篇该方面文章,然后当作一次记录,里面加了少部分的其他内容,其中大部分内容直接使用的引用的博客。

  • jackson:反射+反射缓存、良好的stream支持、高效的内存管理
  • fastjson:
    • jvm虚拟机:通过ASM库运行时生成parser字节码,支持的field不能超过200个。参考:FastJson使用ASM反序列化。
    • android虚拟机:反射的方式。
  • gson:反射+反射缓存、支持部分stream、内存性能较差(gc问题)。

前置知识

ASM

  • ASM是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。
  • ASM能够通过改造既有类,直接生成需要的代码。增强的代码是硬编码在新生成的类文件内部的,没有反射带来性能上的付出。
  • ASM可以用来实现AOP。

反射性能

  • 反射性能相对于对象直接访问性能相差两个数量级(百倍)。
  • 反射很大一部分性能消耗在遍历Field。
  • 反射缓存能够提高1个数量级的性能。
  • 测试数据参考:link。

jackson特性

  • 功能全面、强大:支持stream、databind、path功能。
  • 安装包1.2M,运行时自身占用几百k内存,解析json时内存管理很高效。
  • 实现了较全面、复杂的反射缓存功能,如下

Jackson,fastjson Gson比较_第1张图片

 


Gson特性

  • 安装包143k,运行时自身占用不到100k内存,但解析json时占用内存较多。
  • 通过反射做json的反序列化,缓存反射的Field做反射性能优化,简单直接。如下:

Jackson,fastjson Gson比较_第2张图片


fastjson特性

  • 在jvm虚拟机上使用ASM动态生成反序列化字节码,以此减少反射性能开销;会导致Perm区class增多。
  • 在android平台使用反射的方式实现反序列化,而且性能较差;原因是android独有的dex字节码与java的.class字节码格式不兼容,无法使用ASM。
  • fastjson在android平台性能很低;android平台更适合APT的方式生成代码,比如依赖注入库dagger2,性能很高。

但是近两年fastjson 频频被爆出高危漏洞,真让人唏嘘

然而,FastJson并没有那么流行,有一个最直观的数据,那就是在Maven的中的引用量,和Jackson和Gson不在一个数量级,和Jackson强大的家族更没法比。

有一篇知乎帖子,讨论为什么外国友人不喜欢FastJson。结论就是FastJson是个代码质量不高的国产类库。完全颠覆了我的认知,因为在我的项目中,是经常使用FastJson的,并没有出现什么Bug,而且这段评论是在2016年写的。

Jackson,fastjson Gson比较_第3张图片

所以 如果面试被问到为什么选用FastJson?

因为快!这一个理由就可以把他顶回去了,因为追求快,反而舍弃了很多其他方面,比如java特性的兼容,Json标准规范等。

到现在FastJson已经有了很多的更新,有一些问题也已经修改了,希望fastjson继续坚持。


移动端面临的问题

冷启动问题

  • 由于dalvik、ART虚拟机无反射缓存时性能很差,第一次反序列化json会有很大的时间开销。参考:link。

资源占用问题

  • jackson、gson对象会做反射缓存,占用堆空间,jackson比gson占用内存更大。
  • 解决方案:jackson、gson对象使用单例模式做复用,使用软引用单利对象,允许java内存不够时回收这些内存。
  • jackson支持stream的方式,做网络api的时候可以直接做输入流->Object的转换,优化性能。

Jackson,fastjson Gson比较_第4张图片


gson反序列化/序列化json的时候内存管理不是太好,引发较多gc。gc问题

参考:

https://www.dazhuanlan.com/2020/01/29/5e31a8f46d593/

 

你可能感兴趣的:(工具,java)