2019-12-08 TIL

2019-12-08

Serialize (직렬화)

  • 서로 다른 메모리 공간을 갖는 시스템 간에 오브젝트같은 참조 타입의 데이터를 주고 받기 위해서는 데이터의 직렬화가 필수다.
  • 0xf000같은 주소 값을 보내봐야 상대는 이해할 수 없기 때문이다.
  • 이 주소가 가리키는 오브젝트의 내용을 JSON 혹은 CSV같은 primitive한 값, parse 가능한 데이터로 변환하는 것을 serialize라고 한다.

React Native는 bridge를 통해 JS와 네이티브 간 통신이 이루어지는데 이 때 서로의 데이터를 이해할 수 있도록 JSON 형식으로 직렬화/역직렬화가 반복적으로 일어난다.


직렬화가 뭔지는 모르고 지냈는데 아래 댓글을 통해 알게 되었다!

https://okky.kr/article/224715

Jason Wang 2016-07-27 16:40:43

오래된 글이지만 저도 추가 내용을 달아봅니다. 지붕뚫고높이차 님이 아주 자세하고 정확한 설명을 해 주셨습니다. 저는 좀더 언어 관점에서 설명드리겠습니다.

Java 든 C# 이든 C++ 이던 간에 데이터의 메모리 구조는 크게 다음 2가지로 나뉩니다.

  • 값 형식 데이터: integer, float(single), charactor(또는 char 의 집합인 string) 등
  • 오브젝트(레퍼런스) 형식 데이터: 메모리 번지(주소, Address)값 —> 주소값을 최종적으로 따라가면 값 형식 데이터를 참조 하게 됨. (C/C++) 또는 언어 차원에서 이 과정을 생략해줌 (C#, JAVA) —> 클래스의 인스턴스는 해당 프로세스의 메모리 상에서만 유효한 번지 주소를 갖는 오브젝트(레퍼런스) 데이터.

이 중에 ‘저장/전송 가능한 데이터’ 는 당연하게도 값 형식 데이터만 전송 가능합니다.

오브젝트(레퍼런스) 형태의 참조 데이터(메모리 번지 주소 데이터)는 상식적으로도 파일 저장이나 네트워크 전송이 불가능합니다.

일례로 32비트 시스템에서 Class A 의 인스턴스를 만들었고, 그 참조/주소값이 0x00121212 이었습니다. 그리고 이 참조/주소값 자체도 강제로 파일에 포함 시켜 저장하였습니다. 하지만 다음에 프로그램(서비스)를 다시 Start 시키고 이전에 저장했던 파일에서 0x00121212 참조/주소를 다시 읽어와도 클래스 A 의 인스턴스는 부활 할 수 없으며 이해할 수 도 없는 쓰레기 값일 뿐입니다. 네트워크 전송도 마찬가지로 받는 상대방 입장에서는 전달자가 사용한 참조/주소값 자체는 무의미 합니다. 서로 물리적으로 사용중인 메모리 공간(OS의 가상메모리 포함)은 일치하지 않기 때문입니다.

비트와 바이트와 메모리, 언어 등의 관점에서 이야기를 해보니 이렇습니다. 조금 더 이해를 돕고자 JAVA 언어의 관점에서 설명해 보겠습니다.

자바는 내부적으로 오브젝트(또는 Reference) 형식의 데이터를 많이 사용합니다. 그리고 오브젝트의 주소 메모리 번지 값 접근/편집을 일반적인 JAVA 코딩에 쓰지 않습니다. (언어 차원에서 내부적으로 해결 해 줌)

JAVA 의 클래스 설계에는 오브젝트 안에 오브젝트가 또 들어있을 수 있습니다. (인스턴스 포함 관계)

그것은 오브젝트 안에 내부적으로 다른 오브젝트를 참조할 수 있는 주소값이 담긴 것을 의미합니다.

이 주소값의 실체를 다 끌어와서 Primitive 한 값 형식 데이터로 전부 변조하는 작업을 바로 직렬화(Serialization)라 합니다. —> XML, JSON 등의 데이터 구조를 떠올리면 이해가 빠를것입니다. —> C/C++ 을 해보셨다면 좀 더 이해가 빠를 것입니다. (포인터 데이터를 모두 실제 값의 묶음 형식으로 전달, NPOD 데이터를 POD 데이터로 전달, 그리고 한방에 memcpy!)

그리고 직렬화 된 데이터 형식은 언어에 따라 텍스트로 된 데이터 또는 바이너리 등의 모양을 띄게 됩니다. (어차피 텍스트든 바이너리든 결국 둘 다 Primitive 한 값들의 집합임)

결국 직렬화가 된 데이터는 최종적으로 오브젝트 타입이 없습니다. 모든것이 Primitive 한 값 형식의 데이터 묶음이며, 이것은 파일 저장이나 네트워크 전송시 파싱 할 수 있는 유의미한 데이터가 되는 것입니다. (데이터 중복을 줄이기 위한 테이블화가 일어나는지는 확인 필요. 어차피 이 부분은 언어마다, 규약마다 다를 것)

그리고 또하나 특징은 현존하는 컴퓨터 머신들의 메모리 설계상 큰 데이터 덩어리를 순차적으로 읽어 오는 것이 가장 빠르기 때문에 직렬화 된 데이터는 RDBMS 구조랑은 완전 다르게, 일직선의 연속적인 값들의 집합인 형태를 띄게 됩니다. (대게 그렇습니다. 이것도 언어/규약 마다 다를 수 있습니다) 그래서 이렇게 전송/저장 가능한 데이터를 만드는 행위에 ‘직렬화(Serialization)’ 라는 이름이 붙게 되었습니다.

정리하면 직렬화는 보통 파일 저장이나, 패킷 전송시에 ‘파싱할 수 있는 데이터를 만들기 위해’ 사용됩니다.

+@ 로 프로세스 간에 데이터 전송에도 직렬화된 데이터가 사용 되는 이유는 대부분의 OS 가 현재 가상메모리를 운영 중이며 대부분의 OS 의 프로세스 구현은 서로 다른 가상메모리주소공간(Virtual Address Space, VAS) 를 갖기 때문에 역시 마찬가지로 오브젝트 타입의 참조값(결국 주소값)데이터 인스턴스를 직접 줄 수 없어서 직렬화된 데이터로의 교환을 주로 사용합니다.


Minchang Kim
Minchang Kim
웹/앱 개발자 김민창입니다! 좋은 하루 되세요!