ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JAVA 직렬화(Serialize)란?
    Programming 2022. 3. 20. 21:11
    반응형

     

     

    Serialize(직렬화)가 무엇인가?

     

    객체를 데이터스트림으로 만드는것이다. 

     

    즉 객체에 저장된 데이터를 스트림에 쓰기위해 연속적인 데이터를 변환하는것.

     

    반대로 스트림으로부터 데이터를 읽어 객체를 만드는것은 역직렬화(Deserialization)입니다.

     

    직렬화 사용이유는 객체 자체를 영속적으로 보관할때 사용하는데 파일형태로 저장되어 네트워크를 통해 전송이 가능합니다.

     

    장점으로는 자바와 자바시스템간 개발이 최적화가 되어있어 다른 라이브러리나 추가적인 환경구성이 필요없고

    또한 역직렬화 할 경우 기존 객체처럼 사용이 가능합니다.

     

    JVM(Java Virtual Machine)의 메모리에 상주(힙 or 스택)되어 있는 객체데이터를 바이트로 변환하는 기술입니다.

     

    직렬화방법은 여러 Format이 존재합니다.

    -표형태의 다량데이터를 직렬화 할때 CSV형태

    -구조적인 데이터는 XML, JSON형태

     

    자바에서 객체의 직렬화를 위해 ObjectOutputStream extends OutputStream을 사용합니다.

    스트림에 객체를 출력하기위해 사용합니다 - writeObject()

     

     

    출처 : https://www.c-sharpcorner.com/UploadFile/fd0172/introduction-to-serialization-in-java/

     


    직렬화란?

    객체의 직렬화는 객체의 내용을 바이트 단위로 변환하여 파일 또는 네트워크를 통해서 스트림(송수신)이 가능하도록 하는 것을 의미한다. 
    자바의 I/O 처리는, 정수, 문자열 바이트 단위의 처리만 지원했었다. 따라서 복잡한 내용을 저장/복원 하거나, 네트워크로 전송하기 위해서는 객체의 멤버변수의 각 내용을 일정한 형식으로 만들어(이것을 패킷이라고 한다) 전송해야 했다.
    객체직렬화는 객체의 내용(구체적으로는 멤버변수의 내용)을 자바 I/O가 자동적으로 바이트 단위로 변환하여, 저장/복원하거나 네트워크로 전송할 수 있도록 기능을 제공해준다. 즉 개발자 입장에서는 객체가 아무리 복잡하더라도, 객체직렬화를 이용하면 객체의 내용을 자바 I/O가 자동으로 바이트 단위로 변환하여 저장이나 전송을 해주게 된다. 
    자바에서 직렬화는 자동으로 처리해주는 것이기 때문에, 운영체제가 달라도 전혀 문제되지 않는다. 객체를 직렬화할때 객체의 맴버변수가 다른 객체(Serializable 인터페이스를 구현한)의 레퍼런스 변수인 경우에는 레퍼런스 변수가 가리키는 해당 객체까지도 같이 객체직렬화를 해버린다.
    또 그 객체가 다른 객체를 다시 가리키고 있다면, 같은 식으로 색체 직렬화가 계속해서 일어나게 된다. 이것은 마치 객체직렬화를 처음 시작한 객체를 중심으로 트리 구조의 객체직렬화가 연속적으로 일어나는 것이다. 

     


    직렬화의 장점

    객체 내용을 입출력형식에 구애받지 않고 객체를 파일에 저장함으로써 영속성을 제공한다.
    객체를 네트워크를 통해 손쉽게 교환할 수 있다.

    객체 전송의 단계 

    객체를 분해하여 전송하기 위해서는 직렬화(Serialization) 되어야 한다.
    객체를 전송하기 위해서는 3가지 단계를 거친다.
    (1) 직렬화된 객체를 바이트 단위로 분해한다. (marshalling)
    (2) 직렬화 되어 분해된 데이터를 순서에 따라 전송한다.
    (3) 전송 받은 데이터를 원래대로 복구한다. (unmarshalling) 

    Marshalling

    - 마샬링(Marshalling)은 데이터를 바이트의 덩어리로 만들어 스트림에 보낼 수 있는 형태로 바꾸는 변환 작업을 뜻한다. 
    - 자바에서 마샬링을 적용할 수 있는 데이터는 원시 자료형과 객체 중에서 Serializable 인터페이스를 구현한 클래스로 만들어진 객체이다.
    - 객체는 원시 자료형과 달리 일정한 크기를 가지지 않고 객체 내부의 멤버 변수가 다르기 때문에 크기가 천차만별로 달라진다. 이런 문제점을 처리할 수 있는게 ObjectOutputStream 클래스이다. 

    직렬화 

    - 마샬링으로 바이트로 분해된 객체는 스트림을 통해 전송될 준비가 되었다. 앞에서 언급한대로 객체를 마샬링하기 위해서는 Serializable 인터페이스를 구현한 클래스로 만들어진 객체에 한해서만 마샬링이 진행될 수 있다.
    Serializable 인터페이스는 아무런 메소드가 없고 단순히 자바 버추얼 머신에게 정보를 전달하는 의미만을 가진다.

     

    *직렬화가 가능한 객체의 조건
    (1) 기본형 타입(boolean, char, … )은 직렬화가 가능
    (2) Serializable 인터페이스를 구현한 객체여야 한다.
    (3) 해당 객체의 멤버들 중에 Serializable 인터페이스가 구현되지 않은 객체가 존재해서는 안된다.
    (4) transient가 사용된 멤버는 전송되지 않는다. (보안 변수 : null 전송)

     


    Unmarshalling

    언마샬링은 객체 스트림을 통해서 전달된 바이트 덩어리를 원래의 객체로 복구하는 작업이다. 이 작업을 제대로 수행하기 위해서는 반드시 어떤 객체 형태로 복구할지 형 변환을 정확하게 해주어야 한다. 

    SerialVersionUID, 클래스의 버전관리

    직렬화하면 내부에서 자동으로 SerialVersionUID라는 고유의 번호를 생성하여 관리한다. 이 UID는 직렬화와 역직렬화 할 때 중요한 역할을 한다. 이 값이 맞는지 확인 후 처리하기 때문이다. 만약 이 SerialVersionUID 값이 맞지 않는다면 오류를 출력한다.

     

    객체 생성 당시의 UID와 현재 변경한 이후의 UID는 내부에서 자동으로 생성되어 관리되므로 UID가 달라 오류가 발생할 수 있다. 이러한 문제로 Java에서는 SerialVersionUID를 직접 선언하고 관리하는 방식을 적극 권장하고 있다. 

    결론

     

    객체나 데이터가 어느 특정 메모리상 사용되는데 이 상태그대로 저장하거나 네트워크 전송이 불가능하여

    다른 환경에서 사용할수있게 바꾸는것이 serialize인것 같습니다.

    쉽게 생각하면 직렬화는 바이트 형태로 바꾸는것이라 생각하면 될것같습니다.

     

    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) 를 갖기 때문에 역시 마찬가지로 오브젝트 타입의 참조값(결국 주소값)데이터 인스턴스를 직접 줄 수 없어서 직렬화된 데이터로의 교환을 주로 사용합니다.

     

     

     

    https://ahma.tistory.com/65

     

    Serialize란 무엇인가?

    코드를 쓰다 옆사람이 serialize가 뭔데 썼냐는 말에 저는 그냥 남들이 사용하길래 적었다. 라는 말도안되는 대답을 했습니다. serialize가 무엇이고 왜 사용하는지 궁금하여 기록한 내용입니다. Seria

    ahma.tistory.com

    https://weicomes.tistory.com/63

     

    What is Serializable? 직렬화란 무엇인가??

    [참고] http://lueseypid.tistory.com/42 http://hyeonstorage.tistory.com/252 직렬화란? 객체의 직렬화는 객체의 내용을 바이트 단위로 변환하여 파일 또는 네트워크를 통해서 스트림(송수신)이 가능하도록 하는..

    weicomes.tistory.com

     

    반응형

    'Programming' 카테고리의 다른 글

    Web Server와 WAS(Web Application Server)의 차이  (0) 2023.07.18
    추천사이트 정리  (0) 2021.03.08
Designed by Tistory.