谈谈序列化的作用

article/2025/8/29 23:29:11

文章目录

    • 1. 写在前面
    • 2. 问题阐述
    • 3. 解释
      • 3.1 一些不够完整的解释
      • 3.2 一种完整的解释
        • 3.2.1 去地址
        • 3.2.2 节省空间
    • 4. 小节
    • 参考链接

1. 写在前面

我们应该都用过各种序列化(serialization)的方法(如Python中的pickle.dumps),甚至自己也写过一些序列化的小工具。
维基百科对于序列化的解释比较冗长;相比之下,百度百科的解释更为简单:

序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程

这里面重点强调了两个概念:格式的转变和转变的目的

  • [格式的转变] 转变前的格式是对象状态信息,转变后的格式是“可以存储或传输的形式
  • [转变的目的] 转变成字节流后的目的主要有两个:1. 存储到磁盘; 2. 通过网络进行传输

存储和传输的本质是一样的,都是I/O。我们后面就以磁盘存储为例进行说明。
转变后的格式(即:可存储或传输的形式)比较抽象。因为我们以磁盘存储为例进行说明,为方便表述,我们后面就以“存储格式”简称该转变后的格式。
序列化的作用又可以简单理解为:把内存中的数据存储到磁盘中的过程
那么,一个随之而来的问题便是:

  • 对象状态格式和存储格式的本质区别是什么?
  • 或者:内存数据和磁盘数据的本质区别是什么?

2. 问题阐述

我们知道,内存和磁盘本质上都是存储二进制数据的。
那么,

  1. 为什么不直接把内存中的数据复制一份到磁盘中呢?
  2. 为什么要进行序列化?
  3. 如果只是为了数据持久化,直接进行数据的拷贝可以吗?
  4. 内存中数据格式和磁盘中数据格式的本质区别是什么?
  5. 既然内存和磁盘的存储本质是一样的,不考虑内存和磁盘的数据存取速度差异,使用磁盘直接和cache、CPU进行数据交互可以吗(即跳过内存这一级别)?这个想法似乎和NVM有些不谋而合了。

这些问题其实说的是同一个问题。

3. 解释

3.1 一些不够完整的解释

以上一系列问题中,“为什么要进行序列化”这个问题可能是最直接的。在网上也能搜索到一些答案,包括:

  • 跨语言:某种编程语言(Java)在磁盘上存储的数据,有可能被别的编程语言(C++)读取
  • 跨平台:这个问题在网络传输时更为突出,在A机器上可能为小端序,在B机器上则为大端序

这些答案虽然也有道理,但我觉得还不够完整。
假设我们使用同一门编程语言,在同一个机器上,还需要进行序列化吗?
答案是:可能需要

3.2 一种完整的解释

我们知道,序列化其实主要是进行了数据格式的转换,即从内存格式转换为磁盘格式。
进行该转换还有两个很重要的原因:去地址和节省空间。

3.2.1 去地址

对于一些包含地址或引用的数据结构(如二叉树),对象第一次在内存中的地址,和数据落盘后重新加载到内存中的地址,极有可能是不同的。
因此,需要对这种数据结构的对象,进行一些“去地址”的操作。该操作往往便是通过“序列化”来完成。

可能有人会想到在将对象落盘时,同时记录下对象中的内存地址。第二次加载对象时,按照之前记录的地址进行内存分配。
但内存一般是由多个应用共享的,第二次加载对象时,之前地址对应的内存空间可能已经被占用了。

3.2.2 节省空间

前面提到一个问题:为什么不直接把内存中的数据复制一份到磁盘中呢?
复制操作对于一些简单的数据结构(尤其是内存连续的数据结构)是可行的,比如说一个byte。在不考虑字节顺序(大/小端序)的前提下,一个int也是可行的。实际上,序列化操作对于这些简单数据结构也是这么复制处理的。
但对于二叉树这种复杂的数据结构,复制操作便不可行了。

现代操作系统的内存管理往往了采用了“内存分页”、“逻辑空间”的机制。逻辑空间连续的页面在物理空间中往往是分散的。
对于二叉树这种复杂的数据结构,树中不同的节点可能存储在不同的内存页面中,这些页面分散在内存的不同地方。
如下图所示,一棵二叉树的三个节点分别对应内存中编号为1,10,15的三块内存空间。如果进行简单复制,需要将1~15编号的整块内存数据复制到磁盘中,即使2,3,4等编号的内存空间跟当前二叉树无关。这便造成了严重的磁盘空间浪费
复制

这里引申出另外一个问题:既然物理内存是共享使用的(如,编号为2的内存空间可以由其他对象甚至应用使用),那么磁盘空间可以共享使用吗?如将红色框中的磁盘空间也提供给别的应用使用。这似乎可以解决“磁盘空间浪费”的问题。
理论上这是可以的,但这要求在磁盘管理层面对这些“可共享”的空间进行记录、管理和再分配。相当于在磁盘层面实现一套类似于“内存分页”和“逻辑空间”映射的机制,这大大增加了磁盘管理的复杂度。

采用“序列化”的方法的目的之一,也是为了解决“磁盘空间浪费”的问题。与磁盘层面的管理不同,“序列化”相当于在应用层面进行了管理,将数据更紧密地存储在一起,如下图所示:
序列化

4. 小节

序列化操作的本质是将对象中的字节组织成(顺序的)字节流的过程
序列化的主要目的包括四点:

  • 实现数据的跨语言使用
  • 实现数据的跨平台使用
  • 数据去内存地址
  • 降低磁盘存储空间

实现后两者目的的根本原因是:对象对内存地址的操作

参考链接

  1. Understanding serialization
  2. 维基百科 - 序列化
  3. 百度百科 - 序列化
  4. Why do we use serialization?
  5. Why do we serialize data?
  6. 实体类为啥要序列化

http://chatgpt.dhexx.cn/article/dwbmryb2.shtml

相关文章

Java 之 Serializable 序列化和反序列化的概念,作用的通俗易懂的解释

遇到这个 Java Serializable 序列化这个接口,我们可能会有如下的问题 a,什么叫序列化和反序列化 b,作用。为啥要实现这个 Serializable 接口,也就是为啥要序列化 c,serialVersionUID 这个的值到底是在怎么设置的&#…

cas 原理分析

CAS 原理分析 1、了解java中锁的类型 1.1 悲观锁(Pessimistic Lock) 顾名思义,就是很悲观,假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上…

JAVA中的CAS算法

java 中的线程之间的栈空间是相互独立,堆空间是共享的 V:内存值就是主内存中i值 A:预估值(期望值)就是子线程拿到主内存的值(读取到高速缓存中的值) B:更新值是子线程拿到i值后,修改i的值 假设有两个线程…

面试:CAS算法原理

1、什么是CAS? CAS:Compare and Swap,即比较再交换。 jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的&#x…

CAS原理详解

CAS介绍 CAS全称是Compare And Swap,它的实现和它的字面意思一样,先比较后交换,它是CPU硬件层面的一种指令,从CPU层面能保证"比较并更新"这一段操作的原子性。 与synchronized关键字比较不同是synchronized是一种悲观锁…

CAS算法与ABA问题

锁是用来做并发最简单的方式,当然代价也是最高的。 独占锁是一种悲观锁,synchronized就是一种独占锁;它假设最坏的情况,并且只有在确保其它线程不会造成干扰的情况下执行,会导致其它所有需要锁的线程挂起直到持有锁的…

CAS算法-实现原理

目录 CAS是什么? CAS解决了什么问题? CAS存在什么问题? CAS有哪些应用场景? cas的实现 最后 CAS是什么? CAS的全称为Compare and swap 比较并交换。CAS又经常被称为乐观锁,主要的三个变量,内存值…

并发策略-CAS算法

对于并发控制而言,我们平时用的锁(synchronized,Lock)是一种悲观的策略。它总是假设每一次临界区操作会产生冲突,因此,必须对每次操作都小心翼翼。如果多个线程同时访问临界区资源,就宁可牺牲性…

深入理解CAS算法原理

转载自 深入理解CAS算法原理 1、什么是CAS? CAS:Compare and Swap,即比较再交换。 jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证…

CAS操作原理

1、什么是CAS? CAS:Compare and Swap,即比较再交换。 jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的,这是一…

CAS原理

一、CAS 1.1 CAS概述和作用 CAS的全称是: Compare And Swap(比较相同再交换)。是现代CPU广泛支持的一种对内存中的共享数据进行操作的一种特殊指令。 CAS的作用:CAS可以将比较和交换转换为原子操作,这个原子操作直接由CPU保证。 CAS可以保证…

CAS算法详解

CAS算法 1、CAS概念: CAS是CompareAndSwap的缩写,中文意思是:比较并替换。当要进行CAS操作时,先比较内存地址和原来预期的 地址比较,如果相同,表示这块内存地址没有被修改,可以用新地址替换&…

CAS的原理和使用

CAS 文章目录 CAS一、学习CAS首先了解原子类?1. 何为原子类 二、 CAS是什么1. CAS是什么2. CAS原理3. 使用CAS实例代码4. CAS属于硬件级别保证5. 源码分析 三、CAS底层原理?如果知道,谈谈你对UnSafe的理解1. UnSafe2. 我们知道i线程不安全的&…

对cas算法的理解

cas算法主要关心3个值:内存值V,预期值A,要更新的新值B 如下图所示: 注:t1,t2线程是同时更新同一变量56的值 因为t1和t2线程都同时去访问同一变量56,所以他们会把主内存的值完全拷贝一份到自己…

CAS原理分析

CAS的英文为Compare and Swap 翻译为比较并交换。 CAS加volatile关键字是实现并发包的基石。没有CAS就不会有并发包,synchronized是一种独占锁、悲观锁,java.util.concurrent中借助了CAS指令实现了一种区别于synchronized的一种乐观锁。 什么是乐观锁与…

CAS详解

一、CAS概念 1.1 CAS是什么 Compare And Swap 比较并交换 1. 如果线程的期望值跟物理内存的真实值一样,就更新值到物理内存当中,并返回true 2. 如果线程的期望值跟物理内存的真实值不一样,返回false,那么本次修改失败&#xf…

CAS算法的理解及应用

应用 原子操作类,例如AtomicInteger,AtomicBoolean …适用于并发量较小,多cpu情况下; Java中有许多线程安全类,比如线程安全的集合类。从Java5开始,在java.util.concurrent包下提供了大量支持高效并发访问…

解析CAS算法原理

解析CAS算法原理 什么是CAS?CAS原理概念实现形式底层原理 案例CAS的缺点ABA问题ABA问题如何产生的?原子的引用时间戳原子的引用利用AtomicStampedReference解决ABA问题案例 什么是CAS? CAS,全称Compare And Swap,顾名…

深入解析CAS算法原理

目录 一、CAS的基本概念二、CAS算法理解三、CAS开销四、CAS算法在JDK中的应用 一、CAS的基本概念 CAS:Compare and Swap,即比较再交换,是一种硬件对并发的支持,针对多处理器操作而设计的处理器中的一种特殊指令,用于管…

CAS算法实现

https://blog.csdn.net/bluetjs/article/details/52261490?locationNum15&fps1 1.什么是cas? cas是一种无锁算法(非阻塞算法:一个线程的失败或者挂起不应该影响其他线程的失败或者),是compare and swap的缩写&am…