데이터 직렬화(serialization)란? 데이터 직렬화가 필요한 이유

오늘은 데이터 직렬화가 무엇인지, 왜 해야 하는지에 대해서 알아볼 것이다.

안드로이드의 gRPC에 대해서 공부하던 중 데이터 직렬화라는 개념에 대해서 다시 한번 짚고 넘어가야 할 것 같아서 이렇게 정리하게되었다.



데이터 직렬화(serialization)란?


데이터 직렬화(serialization)를 간단하게 요약하자면

메모리를 디스크에 저장하거나 네트워크 통신에 사용하기 위한 형식으로 변환하는 것 이다.

데이터 직렬화라는 반댓말로 역직렬화라는 말도 있는데 역직렬화(desrialization)는

반대로 디스크에 저장한 데이터를 읽거나, 네트워크 통신으로 받은 데이터를 메모리에 쓸 수 있도록 다시 변환하는 것 이다.

위는 간단하게 요약한 단어이기에 해당 단어만 봤을 때 네트워크 통신을 도와주는 용도정도라고만 짐작이 간다.

그렇다면 한번 자세하게 알아보도록 해보자



직렬화를 사용하는 이유?

데이터는 왜 그냥 사용하면 안되고 직렬화를 해야하는걸까?

우선 메모리(힙, 스택 영역)라는 개념에 대해서 어느정도 이해를 하고 있어야 한다.

개발 언어로 어떤 언어(C, C#, Java 등)를 사용하던지 사용하는 데이터들의 메모리 구조는 크게 2가지로 나뉜다.

1. 값 형식 데이터(Value Type)

  • 우리가 흔히 선언해서 사용하는 int, float, char 등의 값 형식 데이터들은 스택에 메모리가 쌓이고 직접 접근이 가능하다.

2. 참조 형식 데이터(Reference Type)

  • C#에서 Object 타입 혹은 C++에서 포인터 변수들이 여기에 해당된다고 보면 된다. 해당 형식의 변수를 선언하면 힙에 메모리가 할당되며 스택에서는 이 힙 메모리를 참조하는(힙에 메모리 번지 주소를 가지고 있음) 구조로 되어있다.

위의 두가지 데이터 중에서 디스크에 저장하거나 네트워크 통신을 하는 데에는 값 형식 데이터(Value Type)만 가능하다.

참조 형식 데이터의 경우 실제 데이터 값이 아닌 힙에 할당되어 있는 메모리 번지 주소를 가지고 있기에 저장, 통신에 사용할 수 없다.

ex) 포인터 변수 a를 선언하고 객체를 생성하여 그 주소값이 0x00012345라고 가정하고 이 값을 파일에 포함하여 저장했다고 하면, 프로그램 종료 후 재실행 시 기존 주소값을 가져오더라도 a 객체를 가져올 수 없다.(프로그램 종료 시 메모리 사라짐)



직렬화 대상 (Java 기준)

모든 클래스를 직렬화 할 수는 없다.

java.io.Serializable 인터페이스를 구현한 클래스의 객체만 직렬화될 수 있다.

여기서 Serializable 인터페이스는 어떤 멤버변수나 메서드도 가지고 있지 않는 마커 인터페이스(해당 인터페이스를 구현한 클래스가 특정 능력을 가진다고 표시)이다.

하지만 이때 클래스에 보안상 직렬화되면 안되는 값이나 직렬화가 될 수 없는 객체에 대한 참조가 포함된 경우에는 transient라는 제어자를 이용할 수 있다.

transient가 붙은 인스턴스 변수의 값은 그 타입의 기본값으로 직렬화된다.



직렬화 예시

예를 들어서 통화를 한 상대방에게 강아지를 있는 그대로 설명하고 싶지만 사진이나 바디 랭귀지 없이 전화상으로 설명하기엔 어렵다.

이런 상황에서 강아지의 특성을 가진 객체를 생성하여 직렬화한 후 통화 상대방에게 보내게 되면 굉장히 간단해진다.

{ “name”:”Rex”, “age”:5, “favourite_food”: pedigree_choice_cuts, “favourite_game”: fetch_ball, “favourite_hobby”: wagging_tail }

예시 참고 : https://stackoverflow.com/questions/633402/what-is-serialization

Categories:

Updated: