iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Java高性能序列化工具Kryo怎么使用
  • 510
分享到

Java高性能序列化工具Kryo怎么使用

2023-07-02 08:07:17 510人浏览 八月长安
摘要

本文小编为大家详细介绍“Java高性能序列化工具Kryo怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java高性能序列化工具Kryo怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。概述Kryo

本文小编为大家详细介绍“Java高性能序列化工具Kryo怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java高性能序列化工具Kryo怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

    概述

    Kryo 是一个快速序列化/反序列化工具,依赖于字节码生成机制(底层使用了 ASM 库),因此在序列化速度上有一定的优势,但正因如此,其使用也只能限制在基于 JVM 的语言上。

    和 Hessian 类似,Kryo 序列化出的结果,是其自定义的、独有的一种格式。由于其序列化出的结果是二进制的,也即 byte[],因此像 Redis 这样可以存储二进制数据的存储引擎是可以直接将 Kryo 序列化出来的数据存进去。当然你也可以选择转换成 String 的形式存储在其他存储引擎中(性能有损耗)。

    基础用法

    介绍了这么多,接下来我们就来看看 Kryo 的基础用法吧。其实对于序列化框架来说,api 基本都差不多,毕竟入参和出参通常都是确定的(需要序列化的对象/序列化的结果)。在使用 Kryo 之前,我们需要引入相应的依赖。

    <dependency>  <groupId>com.esotericsoftware</groupId>  <artifactId>kryo</artifactId>  <version>5.2.0</version></dependency>

    基本使用如下所示:

    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();       System.out.println(object2.value);  }   static public class SomeClass {       String value;  }}

    Kryo 类会自动执行序列化。Output 类和 Input 类负责处理缓冲字节,并写入到流中。如果序列化前和序列化后类的字段不一致,反序列化会失败。

    Kryo 的序列化

    作为一个灵活的序列化框架,Kryo 并不关心读写的数据,作为开发者,你可以随意使用 Kryo 提供的那些开箱即用的序列化器。

    Kryo 的注册

    和很多其他的序列化框架一样,Kryo 为了提供性能和减小序列化结果体积,提供注册的序列化对象类的方式。在注册时,会为该序列化类生成 int ID,后续在序列化时使用 int ID 唯一标识该类型。

    注册的方式如下:

    kryo.register(SomeClass.class);

    或者

    kryo.register(SomeClass.class, 1);

    可以明确指定注册类的 int ID,但是该 ID 必须大于等于 0。如果不提供,内部将会使用 int++的方式维护一个有序的 int ID 生成。

    Kryo 的序列化器

    Kryo 支持多种序列化器,通过源码我们可窥知一二

    Java高性能序列化工具Kryo怎么使用

    虽然 Kryo 提供的序列化器可以读写大多数对象,但开发者也可以轻松的制定自己的序列化器。篇幅限制,这里就不展开说明了,仅以默认的序列化器为例。

    对象引用

    在新版本的 Kryo 中,默认情况下是不启用对象引用的。这意味着如果一个对象多次出现在一个对象图中,它将被多次写入,并将被反序列化为多个不同的对象。

    举个例子,当开启了引用属性,每个对象第一次出现在对象图中,会在记录时写入一个 varint,用于标记。当此后有同一对象出现时,只会记录一个 varint,以此达到节省空间的目标。此举虽然会节省序列化空间,但是是一种用时间换空间的做法,会影响序列化的性能,这是因为在写入/读取对象时都需要进行追踪。

    开发者可以使用 kryo 自带的 setReferences 方法来决定是否启用 Kryo 的引用功能。

    public class KryoReferenceDemo {    public static void main(String[] args) throws FileNotFoundException {        Kryo kryo = new Kryo();        kryo.register(User.class);        kryo.register(Account.class);        User user = new User();        user.setUsername("alvin");        Account account = new Account();        account.setAccountNo("10000");        // 循环引用        user.setAccount(account);        account.setUser(user);        // 这里需要设置为true,才不会报错        kryo.setReferences(true);        Output output = new Output(new FileOutputStream("kryoreference.bin"));        kryo.writeObject(output, user);        output.close();        Input input = new Input(new FileInputStream("kryoreference.bin"));        User object2 = kryo.readObject(input, User.class);        input.close();        System.out.println(object2.getUsername());        System.out.println(object2.getAccount().getAccountNo());    }    public static class User {        private String username;        private Account account;        public String getUsername() {            return username;        }        public void setUsername(String username) {            this.username = username;        }        public Account getAccount() {            return account;        }        public void setAccount(Account account) {            this.account = account;        }    }    public static class Account {        private String accountNo;        private String amount;        private User user;        public String getAccountNo() {            return accountNo;        }       public void setAccountNo(String accountNo) {            this.accountNo = accountNo;        }        public String getAmount() {            return amount;        }        public void setAmount(String amount) {            this.amount = amount;        }        public User getUser() {            return user;        }        public void setUser(User user) {            this.user = user;        }    }}

    如果序列化前的setReferences(false), 后面设置setReferences(true)进行反序列化,会失败。

    线程安全

    Kryo 不是线程安全的。每个线程都应该有自己的 Kryo 对象、输入和输出实例。

    因此在多线程环境中,可以考虑使用 ThreadLocal 或者对象池来保证线程安全性。

    ThreadLocal + Kryo 解决线程不安全

    ThreadLocal 是一种典型的牺牲空间来换取并发安全的方式,它会为每个线程都单独创建本线程专用的 kryo 对象。对于每条线程的每个 kryo 对象来说,都是顺序执行的,因此天然避免了并发安全问题。创建方法如下:

    static private final ThreadLocal<Kryo> kryos = new ThreadLocal<Kryo>() {  protected Kryo initialValue() {     Kryo kryo = new Kryo();     // 在此处配置kryo对象的使用示例,如循环引用等     return kryo;  };};Kryo kryo = kryos.get();

    之后,仅需要通过 kryos.get() 方法从线程上下文中取出对象即可使用。

    对象池 + Kryo 解决线程不安全

    「池」是一种非常重要的编程思想,连接池、线程池、对象池等都是

    「复用」思想的体现,通过将创建的“对象”保存在某一个“容器”中,以便后续反复使用,避免创建、销毁的产生的性能损耗,以此达到提升整体性能的作用。

    Kryo 对象池原理也是如此。Kryo 框架自带了对象池的实现,整个使用过程不外乎创建池、从池中获取对象、归还对象三步,以下为代码实例。

    // Pool constructor arguments: thread safe, soft references, maximum capacityPool<Kryo> kryoPool = new Pool<Kryo>(true, false, 8) {  protected Kryo create () {     Kryo kryo = new Kryo();     // Kryo 配置     return kryo;  }};// 获取池中的Kryo对象Kryo kryo = kryoPool.obtain();// 将kryo对象归还到池中kryoPool.free(kryo);

    创建 Kryo 池时需要传入三个参数,其中第一个参数用于指定是否在 Pool 内部使用同步,如果指定为 true,则允许被多个线程并发访问。第三个参数适用于指定对象池的大小的,这两个参数较容易理解,因此重点来说一下第二个参数。

    如果将第二个参数设置为 true,Kryo 池将会使用 java.lang.ref.SoftReference 来存储对象。这允许池中的对象在 JVM 的内存压力大时被垃圾回收。Pool clean 会删除所有对象已经被垃圾回收的软引用。当没有设置最大容量时,这可以减少池的大小。当池子有最大容量时,没有必要调用 clean,因为如果达到了最大容量,Pool free 会尝试删除一个空引用。

    创建完 Kryo 池后,使用 kryo 就变得异常简单了,只需调用 kryoPool.obtain() 方法即可,使用完毕后再调用 kryoPool.free(kryo) 归还对象,就完成了一次完整的租赁使用。

    理论上,只要对象池大小评估得当,就能在占用极小内存空间的情况下完美解决并发安全问题。如果想要封装一个 Kryo 的序列化方法,可以参考如下的代码

    public static byte[] serialize(Object obj) {   Kryo kryo = kryoPool.obtain();   // 使用 Output 对象池会导致序列化重复的错误(getBuffer返回了Output对象的buffer引用)   try (Output opt = new Output(1024, -1)) {       kryo.writeClassAndObject(opt, obj);       opt.flush();       return opt.getBuffer();  }finally {       kryoPool.free(kryo);  }}

    读到这里,这篇“Java高性能序列化工具Kryo怎么使用”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网精选频道。

    --结束END--

    本文标题: Java高性能序列化工具Kryo怎么使用

    本文链接: https://www.lsjlt.com/news/340606.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • Java高性能序列化工具Kryo怎么使用
      本文小编为大家详细介绍“Java高性能序列化工具Kryo怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java高性能序列化工具Kryo怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。概述Kryo ...
      99+
      2023-07-02
    • Java高性能序列化工具Kryo详情
      目录概述基础用法Kryo 的序列化Kryo 的注册Kryo 的序列化器对象引用线程不安全ThreadLocal + Kryo 解决线程不安全对象池 + Kryo 解决线程不安全小结概...
      99+
      2024-04-02
    • java原生序列化和Kryo序列化性能实例对比分析
      简介最近几年,各种新的高效序列化方式层出不穷,不断刷新序列化性能的上限,最典型的包括:专门针对Java语言的:Kryo,FST等等跨语言的:Protostuff,ProtoBuf,Thrift,Avro,MsgPack等等这些序列化方式的性...
      99+
      2023-05-31
      java kryo 序列化
    • 如何使用JID来进行Java对象的高性能序列化
      如何使用JID来进行Java对象的高性能序列化,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。JID 是一个用来反序列化、更新和重新序列化 Map 对象,在 i5...
      99+
      2023-06-17
    • OpenStack高性能监控工具Monasca怎么用
      小编给大家分享一下OpenStack高性能监控工具Monasca怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!介绍Monasca 是一个多租户监控即服务工具...
      99+
      2023-06-17
    • Tensorflow高性能数据优化增强工具Pipeline使用详解
      目录安装方法功能高级用户部分用例1,为训练创建数据Pipeline用例2,为验证创建数据Pipeline初学者部分Keras 兼容性配置增强:GridMaskMixUpRandomE...
      99+
      2024-04-02
    • java自定义序列化的具体使用
      目录1.问题引出 2.解决办法 3.另外一种自定义序列化机制(介绍Externalizable) 1.问题引出 在某些情况下,我们可能不想对于一个对象的所有field进行序列化,例...
      99+
      2024-04-02
    • Java序列化与反序列化怎么应用
      这篇“Java序列化与反序列化怎么应用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java序列化与反序列化怎么应用”文章吧...
      99+
      2023-07-05
    • NumPy和Apache:如何在Java应用程序中使用这些工具来提高性能?
      在当今的数据科学和人工智能领域中,Python和NumPy已成为最常见的工具之一。Python和NumPy提供了各种方便的数据结构和算法,使得数据处理和分析变得更加容易。与此同时,Apache Hadoop和Spark等工具被广泛用于大数...
      99+
      2023-11-14
      apache numy load
    • Android性能测试工具SoloX怎么使用
      这篇文章主要介绍“Android性能测试工具SoloX怎么使用”,在日常操作中,相信很多人在Android性能测试工具SoloX怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大...
      99+
      2024-04-02
    • Linux一体化性能监测工具collectl怎么用
      Linux一体化性能监测工具collectl怎么用,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。对Linux系统管理员来说,最重要的任务莫过于确保他或她管理的系统处于非常良好的...
      99+
      2023-06-16
    • java集合排序工具类怎么使用
      Java集合排序工具类可以使用`java.util.Collections`类中的静态方法来实现。以下是使用Java集合排序工具类的...
      99+
      2023-10-26
      java
    • 服务器性能测试工具怎么使用
      服务器性能测试工具可以帮助测试服务器的性能表现,下面是使用步骤:1. 选择一款适合您的服务器的性能测试工具,例如Apache JMe...
      99+
      2023-06-04
      服务器性能测试工具 服务器
    • Java全能工具类之Hutool怎么使用
      本篇内容主要讲解“Java全能工具类之Hutool怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java全能工具类之Hutool怎么使用”吧!Hutool简介Hutool是一个Java工...
      99+
      2023-07-05
    • 高性能的内网穿透工具frp使用场景
      目录什么是 frp为什么使用 frp安装使用使用场景统一的服务端配置SSH 连接内网服务器暴露内网 HTTP 服务TCP 类型HTTP 类型静态文件下载服务本文将分享一个很好用的内网...
      99+
      2024-04-02
    • C#中如何使用性能测试工具和性能优化技巧
      C#中如何使用性能测试工具和性能优化技巧,需要具体代码示例性能优化在软件开发过程中起着非常重要的作用,它可以提高系统的性能、运行速度和响应能力。C#是一种高性能的编程语言,也有许多性能优化技巧和工具可以帮助我们更好地利用C#的优势。本文将介...
      99+
      2023-10-22
      性能优化技巧 C#性能测试工具
    • Netty分布式高性能工具类recycler如何使用
      这篇文章主要介绍了Netty分布式高性能工具类recycler如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Netty分布式高性能工具类recycler如何使用文章都会有所收获,下面我们一起来看看吧。r...
      99+
      2023-06-29
    • 怎么在python中使用序列化与反序列化
      这篇文章将为大家详细讲解有关怎么在python中使用序列化与反序列化,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。python有哪些常用库python常用的库:1.requesuts;2.s...
      99+
      2023-06-14
    • 为什么不使用Java序列化
      这篇文章主要介绍“为什么不使用Java序列化”,在日常操作中,相信很多人在为什么不使用Java序列化问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”为什么不使用Java序列化”的疑惑有所帮助!接下来,请跟着小编...
      99+
      2023-06-15
    • 怎么用java实现序列化
      这篇文章主要介绍怎么用java实现序列化,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!package test;import java.io.*;public class Test implements Serial...
      99+
      2023-06-03
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作