개발 기록

> [Java] 직렬화 (Serializable) 에 대해서 2. 의문점과 답변 정리 본문

JAVA

> [Java] 직렬화 (Serializable) 에 대해서 2. 의문점과 답변 정리

1z 2020. 10. 2. 11:05

 

 

1. 개념 

직렬화:  객체를 정적 바이트 스트림으로 변환하는 기술 
역직렬화 : 바이트로 변환된 데이터를 다시 객체로 변환하는 기술
여기서 객체는 JVM(Java Virtual Machine 이하 JVM)의 메모리에 상주(힙 또는 스택)되어 있는 객체 데이터를 말한다.

2. 질문과 답변 

 

질문1

서비스 객체나 컨트롤러 객체는 직렬화하지 않는데 도메인 객체(DB에서 읽어온 내용을 담는 객체)는 꼭 implement serializable로 직렬화 하는 이유

 

답변1

서버가 다중화되어 있고 세션 클러스터링을 통해 세션관리를 하는 환경이라 가정했을 때 도메인 객체가 세션에 저장이 될때 도메인 객체에 Serializable 인터페이스 클래스를 구현해야지 정상적으로 세션에 저장하고 꺼내올수 있다. 
도메인 객체가 세션에 저장하지 않는 단순한 데이터 집합이고 컨트롤러에서 생성되어서 뷰에서 소멸하는 데이터의 전달체라면 객체 직렬화는 고려하지 않아도 되는 부분이다.

 

답변2

서버가 다중화되지 않고 단일화되어 있을때는 서버설정에 따라 직렬화 여부가 나뉜다. 세션관리를 스토리지나 네트웍자원을 사용한다고 하면 객체 직렬화를 해야 하고 메모리에서만 관리한다면 객체직렬화를 할 필요가 없다. 둘다 고려한다면 무조건 객체직렬화를 해야 한다.

 

답변3

데이터 타입 종류는 크게 다음 2가지로 나뉜다. 이 중에 '저장/전송 가능한 데이터' 는 값 형식 데이터만 전송 가능하다.

기본형 타입(Primitive Type)
*값형식 데이터*
참조형 타입(Reference Type)
* 메모리 주소 값*
숫자(Number)
문자열(String)
불리언(Boolean)
null
undefined
심볼(Symbol)
객체(Object)
배열(Array)
함수(Function)
날짜(Date)
정규표현식(RegExp)
Map
WeakMap
Set
WeakSet

 

 

객체의 주소값을 최종적으로 따라가면 값 형식 데이터를 참조 하게 되는데, 만일 이 주소값을 파일로 전송한다고 해도 서로 물리적으로 사용중인 메모리 공간(OS의 가상메모리 포함)은 일치하지 않기 때문에 상대방 입장에서는 무의미한 값이 된다.

즉 JAVA 클래스의 인스턴스는 해당 프로세스의 메모리 상에서만 사용 가능한 유효한 번지 주소를 갖는다. 

 

- 예시.

1.  Class A 의 인스턴스를 만들었고, 그 참조/주소값이 0x00121212 이라고 했을 때 이 참조/주소값 자체도 강제로 파일에 포함 시켜 저장함

2. 다음에 프로그램(서비스)를 다시 Start 시키고 이전에 저장했던 파일에서 0x00121212 참조/주소를 다시 읽어옴

3. 클래스 A 의 인스턴스는 부활 할 수 없으며 이해할 수 도 없는 쓰레기 값일 뿐이다. 

 

- 결론. 

주소값의 실체를 다 끌어와서 Primitive 한 값 형식 데이터로 전부 변조하는 작업을 바로 직렬화(Serialization)라 한다.

그리고 직렬화 된 데이터 형식은 언어에 따라 텍스트로 된 데이터 또는 바이너리 등의 모양은 다르지만 결국  Primitive 한 값들의 집합이다.

이것은 파일 저장이나 네트워크 전송시 파싱 할 수 있는 유의미한 데이터가 되는 것이다.

 


 

▶ 질문2

프로세스 간에 데이터 전송에도 직렬화된 데이터가 사용 되는 이유

 

답변1

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

 


 

 

▶ 질문3

자바 직렬화는 언제(when) 어디서(where) 사용되나요?

 

 

답변1

- JVM의 메모리에서만 상주되어있는 객체 데이터를 그대로 영속화(Persistence)가 필요할 때 사용된다.
시스템이 종료되더라도 없어지지 않는 장점을 가지며 영속화된 데이터이기 때문에 네트워크로 전송도 가능하다. 그리고 필요할 때 직렬화된 객체 데이터를 가져와서 역직렬 화하여 객체를 바로 사용할 수 있다.

 

* 자바 직렬화 사용처

ⓛ 서블릿 세션 (Servlet Session)
서블릿 기반의 WAS(톰캣, 웹로직 등)들은 대부분 세션의 자바 직렬화를 지원하고 있다.
단순히 세션을 서블릿 메모리 위에서 운용한다면 직렬화를 필요로 하지 않지만, 파일로 저장하거나 세션 클러스터링, DB를 저장하는 옵션 등을 선택하게 되면 세션 자체가 직렬화가 되어 저장되어 전달됩니다.

 

② 캐시 (Cache)
자바 시스템에서 퍼포먼스를 위해 캐시(Ehcache, Redis, Memcached,...)라이브러리를 시스템을 많이 이용하게 되는데 이렇게 캐시 할 부분을 자바 직렬화된 데이터를 저장해서 사용된다. 물론 자바 직렬화만 이용해서만 캐시를 저장하지 않지만 가장 간편하기 때문에 많이 사용된다.

 

③ 자바 RMI(Remote Method Invocation) 최근에는 많이 사용되지 않음
자바 RMI는 원격 시스템 간의 메시지 교환을 위해서 사용하는 자바에서 지원하는 기술로 보통은 원격의 시스템과의 통신을 위해서 IP와 포트를 이용해서 소켓통신을 해야 하지만 RMI는 그 부분을 추상화하여 원격에 있는 시스템의 메서드를 로컬 시스템의 메서드인 것처럼 호출할 수 있다. 원격의 시스템의 메서드를 호출 시에 전달하는 메시지(보통 객체)를 자동으로 직렬화 시켜 사용된다.  그리고 전달받은 원격 시스템에서는 메시지를 역직렬화를 통해 변환하여 사용된다.

 


 

 

▶ 질문4

왜 다양한 직렬화(csv, json) 방법중에 자바 직렬화를 사용하나요?

 

답변1

CSV, JSON, 프로토콜 버퍼 등은 시스템의 고유 특성과 상관없는 대부분의 시스템에서의 데이터 교환 시 많이 사용되지만  "자바 직렬화 형태의 데이터 교환은 자바 시스템 간의 데이터 교환을 위해서 존재한다."고 생각하시면 된다.

 

 


 

 

▶ 질문5

자바에서도 CSV, JSON을 사용하면 되지 자바 직렬화를 써야 되는 이유가 있나요?

 

답변1

장점과 단점을 살펴보고  목적에 따라 적절하게 구분하여 사용하면 된다.

 

 

-장점

자바 직렬화는 자바 시스템에서 개발에 최적화되어 있다. 복잡한 데이터 구조의 클래스의 객체라도 직렬화 기본 조건만 지키면 큰 작업 없이 바로 직렬화/역직렬화가 가능하다. 가장 잘 보이는 장점 중 하나는 데이터 타입이 자동으로 맞춰지기 때문에 관련 부분을 큰 신경을 쓰지 않아도 된다는 것이다. 그래서 역직렬화 시 기존 객체처럼 바로 사용할 수 있다.

 

- 단점

타입에 대한 정보 등 클래스의 메타 정보도 가지고 있기 때문에 Json 같이 최소의 메타정보만 갖는 포맷보다 데이터가 많아진다. 참고로, 직렬화 시킨 결과물이 json 형태로 직렬화 한것과 비교했을 때, 훨씬 용량이 크다는 점이 자바 직렬화의 단점 중 하나이다.

 

 

 

 

출처

https://techblog.woowahan.com/2550/

https://okky.kr/article/224715