티스토리 뷰

CS

직렬화(Serialization)

기억용블로그 2022. 8. 26. 15:48
728x90

직렬화

직렬화란 서로 다른 머신(PC, 스마트폰 등)끼리 객체를 주고받기 위한 방법으로 객체를 바이트스트림으로 변환하여 네트워크를 통해 데이터를 주고받는 것이 가능해진다.

 

직렬화의 필요성

CPU나 RAM과 같은 리소스를 공유하는 하나의 머신 내에서 객체를 주고받아야 한다고 가정해보자. 이때 객체는 프로세스 RAM의 힙 영역에 저장되어 있고 프로세스의 RAM은 OS의 커널에서 가상화하여 제공한 것이므로 커널의 IPC를 통해 해당 값에 쉽게 접근하여 사용할 수 있다. 단지 메모리 주소를 아는 것만으로도 객체에 접근이 가능하다는 뜻이다.

 

하지만 리소스를 공유하지 않는 서로 다른 머신에서 네트워크를 통해 객체를 주고받아야 한다면 어떻게 해야할까? 메모리의 주소값을 주고받더라도 해당 주소값은 서로 다른 머신끼리는 서로 다른 값을 가르키기 때문에 메모리 주소값에 독립적인 다른 방식을 사용해야 한다.

이때 사용하는 방법이 직렬화이다. 객체를 바이트스트림으로 변환하여 다른 머신에서도 해당 값을 읽을 수 있게 하는 것이다.

 

자바의 직렬화 과정

 

아래의 코드를 통해 SerialTest 객체를 생성한다고 가정해보자.

class parent implements Serializable {
	int parentVersion = 10;
}

class contain implements Serializable{
	int containVersion = 11;
}

public class SerialTest extends parent implements Serializable {
	int version = 66;
	contain con = new contain();

	public int getVersion() {
		return version;
	}
	public static void main(String args[]) throws IOException {
		FileOutputStream fos = new FileOutputStream("temp.out");
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		SerialTest st = new SerialTest();
		oos.writeObject(st);
		oos.flush();
		oos.close();
	}
}

 

SerialTest 객체가 바이트스트림으로 변환된 형태는 다음과 같다.

AC ED 00 05 73 72 00 0A 53 65 72 69 61 6C 54 65
73 74 05 52 81 5A AC 66 02 F6 02 00 02 49 00 07
76 65 72 73 69 6F 6E 4C 00 03 63 6F 6E 74 00 09
4C 63 6F 6E 74 61 69 6E 3B 78 72 00 06 70 61 72
65 6E 74 0E DB D2 BD 85 EE 63 7A 02 00 01 49 00
0D 70 61 72 65 6E 74 56 65 72 73 69 6F 6E 78 70
00 00 00 0A 00 00 00 42 73 72 00 07 63 6F 6E 74
61 69 6E FC BB E6 0E FB CB 60 C7 02 00 01 49 00
0E 63 6F 6E 74 61 69 6E 56 65 72 73 69 6F 6E 78
70 00 00 00 0B

 

프로토콜에 대한 정보

AC ED : STREAM_MAGIC. 해당 바이트스트림이 직렬화 프로토콜이라는 것을 명시한다.

00 05 : STREAM_VERSION. 직렬화 버전.

0x73 : TC_OBJECT. new Object라는 것을 명시한다.

 

SerialTest 클래스에 대한 정보

0x72 : TC_CLASSDESC. 새로운 클래스라는 것을 명시한다.

00 0A : 클래스 이름의 길이.

53 65 72 69 61 6c 54 65 73 74 : 클래스 이름. "SerialTest"

05 52 81 5A AC 66 02 F6 : 해당 클래스의 serialVersionUID.

0x02 : 플래그. 객체가 직렬화 가능함을 의미한다.

00 02 : 클래스 내부에 있는 필드 개수.

 

SerialTest의 첫 번째 필드인 int version = 66;에 대한 정보

0x49 : 필드 타입 코드. 49는 Int의 "I"를 의미한다.

00 07 : 필드명의 길이.

76 65 72 73 69 6F 6E : 필드명. "version"

 

그 다음 필드인 contain con = new contain();에 대한 메타 데이터 

0x74 : TC_STRING. new String임을 의미.

00 09 : 스트링의 길이.

4C 63 6F 6E 74 61 69 6E 3B : Lcontain; 표준 JVM 서명.

0x78 : TC_ENDBLOCKDATA. 데이터의 끝을 알림.

 

SerialTest의 슈퍼클래스인 parent 클래스에 대한 정보

0x72 : TC_CLASSDESC. 새로운 클래스라는 것을 명시한다.

00 06 : 클래스 이름의 길이.

70 61 72 65 6E 74 : 클래스 이름. "SerialTest"

0E DB D2 BD 85 EE 63 7A : 해당 클래스의 serialVersionUID.

0x02 : 플래그. 객체가 직렬화 가능함을 의미한다.

00 02 : 클래스 내부에 있는 필드 개수.

 

parent 클래스의 첫 번째 필드인 int version = 100;에 대한 정보

0x49 : 필드 타입 코드. 49는 Int의 "I"를 의미한다.

00 0D : 필드명의 길이.

70 61 72 65 6E 74 56 65 72 73 69 6F 6E : 필드명. "parentVersion"

0x78 : TC_ENDBLOCKDATA. 데이터의 끝을 알림.

0x70 : TC_NULL. parent 클래스의 슈퍼클래스가 더 이상 존재하지 않음을 명시함.

 

00 00 00 0A : parentVersion의 값 10.

 

	int version = 66;

00 00 00 42 : version의 값 66.

 

 

contain con = new contain();

contain 객체에 대한 정보

0x73 : TC_OBJECT.

0x72 : TC_CLASSDESC. 

00 07 : 클래스명의 길이.

63 6F 6E 74 61 69 6E : 클래스명. "contain"

FC BB E6 0E FB CB 60 C7 : 해당 클래스의 serialVersionUID.

0x02 : 플래그. 객체가 직렬화 가능함을 의미한다.

00 01 : 클래스 내부에 있는 필드 개수.

 

contain 객체의 필드 int containVersion = 11;에 대한 정보

0x49 : 필드 타입 코드. 49는 Int의 "I"를 의미한다.

00 0E : 필드명의 길이.

70 61 72 65 6E 74 56 65 72 73 69 6F 6E : 필드명. "containVersion"

0x78 : TC_ENDBLOCKDATA.

0x70 : TC_NULL.

 

00 00 00 0B : containVersion의 값 11.

 

레디스에 직렬화가 필요한 이유

레디스에 객체를 저장할때 직렬화하여 저장해야 한다. 위 직렬화 과정에서 볼 수 있듯이 바이트스트림으로 변환된 객체는 메타데이터를 포함한 모든 데이터를 하나의 스트림으로 저장하여 메모리 주소값에 독립적으로 동작할 수 있게 하는 것이다. 

 

DB의 영속성과 관계없이 레디스가 인메모리 데이터베이스로 동작하기 위해서는 메모리에 독립적으로 값을 저장할 필요가 있고 이를 위해서 레디스에는 직렬화한 데이터가 저장되는 것이다.

 

 

레퍼런스

https://www.infoworld.com/article/2072752/the-java-serialization-algorithm-revealed.html

 

The Java serialization algorithm revealed

Serialization is the process of saving an object's state to a sequence of bytes; deserialization is the process of rebuilding those bytes into a live object. The Java Serialization API provides a standard mechanism for developers to handle object serializa

www.infoworld.com

 

'CS' 카테고리의 다른 글

Base64 인코딩  (0) 2022.11.03
Stub, Fake, Mock, Dummy, Spy  (2) 2022.09.19
URI, URL, URN의 차이점  (0) 2022.08.25
트랜잭션 격리 수준  (0) 2022.08.25
배치나 스케줄러와 같은 cron daemon은 내부적으로 어떻게 동작할까?  (0) 2022.08.16
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함