lord2205
501
2013-07-02 13:18:57
20
30750

직렬화 하는 이유가?


자바책에는 객체를 파일에 저장하거나 파일에서 꺼내오기 위해서 또는 객체를 네트워크를 통해 전송하기 위해서는 미리 객체를 직렬화해야한다고 되어 있네요.

웹 어플 소스 분석하다보면
서비스 객체나 컨트롤러 객체는 직렬화하지 않는데
도매인 객체(DB에서 읽어온 내용을 담는 객체)는
꼭 implement serializable로 직렬화 하는데
이유가 궁긍합니다.

소스상에는 도메인 객체를 파일로 저장하거나 네트워크 전송하는 부분이 없어서 물어봅니다.


1
8
  • 답변 20

  • 무명소졸
    5k
    2013-07-02 12:18:16
    도메인 정보를 담고 있으니까요...
    -1
  • 하마
    6k
    2013-07-02 12:20:17
    직렬화 안하고..
    현상태를 어떻게 저장해두실거죠? (메멘토패턴)

    직렬화 안하고
    현 상태를 원격지에 어떻게 송신을 하실거죠? (프록시패턴)

    반대로 생각해보시길..
    -1
  • 스타
    3k
    2013-07-02 12:38:11
    더 쉽게 이야기하면 여러 타입의 데이터를 문자타입으로 만들어야 데이터를 주고 받을 수 있기 때문.
    1
  • lord2205
    501
    2013-07-02 12:39:22
    아직 학생이고 직렬화에 대해 모릅니다. 책에 나와있는것도 굉장히 짧아서 잘모르겟어요.
    0
  • 스타
    3k
    2013-07-02 12:42:38
    디비서버는 중국 사람, 웹서버는 한국 사람으로 생각하면
    내 생각을 다른 사람과 의사소통을 하기 위해선
    서로 알아듣는 영어라는 언어가 필요하지요.
    그 영어 부분이 직렬화일테고 각각의 언어는 씨나 자바나 여러가지가 될거에요
    0
  • lord2205
    501
    2013-07-02 12:44:21
    코드를 봐도
    도메인 객체를
    어딘가에 저장해두거나 송신을 하는 부분은 없어서 물어본 겁니다.
    예를 들면 쇼핑몰 어플에서 상품 정보를 담는 도메인 객체가 직렬화되어 있네요.
    0
  • 스타
    3k
    2013-07-02 12:47:20
    통신이 꼭 서버간에만 일어나는건 아니고, 프로그램간, 모듈간에도 일어날건데요
    0
  • 스타
    3k
    2013-07-02 12:50:39
    그런걸 물은게 아니면 ㅈㅅ ㅜㅜ
    네트워크 통신을 학 위해서 직렬화 해야 하는게
    직렬화를 네트워크 통신에만 쓴다는 말은 아닌 듯
    0
  • cynicjj
    1k
    2013-07-02 12:58:13
    파일, 통신이 주 용도지만 메모리에 저장 할 때도 씁니다.
    톰캣 세션에 저장하려면 필요하죠.
    세션 클러스터링에서 쓰는 건 덤.
    0
  • LaZyDev
    301
    2013-07-02 13:00:56
    serialization 이 직렬화군요 -_=;;

    must는 아닌데 should이죠
    0
  • naveyoungho
    943
    2013-07-02 13:05:27
    단순히 생각하면 특정 정보(객체)등이 메모리상에 올라가 있는데 물리적으로 여기저기 분포되어 있거나 또는 메모리 특성에 맞게 data들이 관리 되고 있습니다. 이런 정보를 네트워크를 통해 다른곳에 보내거나 파일로 저장하기 위해 직렬화라는 변환 과정을 거쳐 놓는다고 이해하세용
    0
  • lord2205
    501
    2013-07-02 13:22:51
    답변 감사합니다. 에디님 답글이 제가 원하던 답이네요.
    도메인 객체에 보면 이런 맴버변수가 들어가 있는데
    private static final long serialVersionUID = 8329559983943337176L;
    용도를 모르겟어요;
    0
  • 스타
    3k
    2013-07-02 13:31:59
    아.... 왜 쓰는지 이유를 물어보고, 활용하는 예를 답변으로 채택하시다니 ㅜㅜ
    0
  • 99퍼센트
    431
    2013-07-02 13:38:17
    "소스상에는 도메인 객체를 파일로 저장하거나 네트워크 전송하는 부분이 없어서 물어봅니다. "
    실제 없는 경우가 많습니다.
    해당 프로그램에서는 직열화할일이 (현 시점까지는) 없었던 거죠.
    추후 프로그램을 확장할 때, 네트웍이나 파일저장일 필요할 경우 직열화된 클래스를 저장하거나
    전송할 수 있겠죠.

    직열화의 개념은 단순합니다. 메모리 상에 존재하는 클래스인스턴스를 어떻게 파일로 저장하거나,
    외부로 보낼까에 대한 고민으로 나온 것입니다.
    그리고 위 serialVersionUID의 경우

    파일로 저장된 바이트 스트림을 읽어 해석할 경우를 생각해보세요.
    읽은 바이트 스트림이 어떤 클래스에 매핑되어 인스턴스화 되어야 할지를요..
    serialVersionUID 도 함께 바이트스트림으로 저장되기 때문에,
    이를 읽은 후 정확한 해당클래스를 찾을 수 있지요.
    0
  • 무명소졸
    5k
    2013-07-02 14:00:42
    serialVersionUID 사용하는 이유는 type safely 을 위해서에요

    예를들어 직렬화한 객체를 원격지에 전송을 했다고 했을경우에
    전송된 객체의 클래스와 원격지의 클래스와 동일한지 여부 체크를 해주는거에요.
    serialVersionUID 다를경우 java.io.InvalidClassException 을 발생합니다.
    (원격지에도 해당 클래스가 있어야지 객체를 사용할수있겠죠)
    1
  • 지붕뚫고높이차
    766
    2013-07-02 14:44:40
    간단하게 이야기 드리면

    서버가 다중화(여러개존재) 되어 있고
    세션 클러스터링을 통해 세션관리를 하는 환경에서

    도메인 객체가 세션에 저장이 될때

    도메인 객체에
    Serializable 인터페이스 클래스를 구현하기(implements) 해야지
    정상적으로 세션에 저장하고 꺼내올수 있기 때문입니다.

    도메인 객체가 세션에 저장하지 않는 단순한 데이터 집합이고
    컨트롤러에서 생성되어서 뷰에서 소멸하는 데이터의 전달체라면
    객체 직렬화는 고려하지 않아도 되는 부분입니다.

    그리고 중간에 패턴 이야기가 나왔는데
    메멘토 나 프록시 패턴에서 사용하는 객체는
    도메인 객체의 성격보다는

    메소드와 데이터를 포함하는 일반적인 객체 형태라서
    질문하신 도메인 객체의 직렬화와 다른 내용인것 같아서
    덧 붙입니다.


    그런 점에서 보면

    생각하지 않고
    다른 코드에 적용되어 있으니 관습적으로
    Serializable 를 구현한 도메인 객체를 많이 보시게 될거에요.



    그런데

    귀찮게 Serializable 인터페이스를 구현해야지만
    객체 직렬화가 가능할까요?

    모든
    클래스와 그 클래스의 인스턴스, 데이터 집합은
    컴퓨터 메모리에 잘 정렬되어
    CPU 가 잘 사용하고 있고

    메모리에 로드되어 있는 바이트 배열을
    그대로 스토리지에 저장하거나
    네트웍을 통해 다른 프로세스(JVM) 에 전달할 수 있는데

    도대체 왜 Serializable 인터페이스가 필요한지 궁금해 하신분 계세요?




    제 생각은 JVM 설계할때 인터페이스를 좋아하는 아키텍쳐가

    객체 직렬화는
    Serializable 인터페이스를 구현한 것 만
    가능하게 설계한다!

    라는 이유가 아닐까 추측합니다.
    (추측입니다. 다른 이유를 아시는분은 알려주세요.)

    jdk/jvm 설계자가 그렇게 인터페이스를 정의하니
    자바 개발자는
    그 규칙을 따라야 하는거라고 생각합니다.
    1
  • lord2205
    501
    2013-07-02 14:52:08
    지붕뚫고높이차님//
    자세한 설명 감사합니다.
    서버가 다중화되지 않고 단일화되어 있을때는
    도메인 객체를 직렬화하지 않아도 도메인 객체를 세션에 저장할 수 있나요?
    0
  • 지붕뚫고높이차
    766
    2013-07-02 14:55:20
    그건 서버설정에 따라 다릅니다.

    세션관리를 스토리지나 네트웍자원을 사용한다고 하면 객체 직렬화를 해야 하고
    메모리에서만 관리한다면 객체직렬화를 할 필요가 없습니다.

    둘다 고려한다면 무조건 객체직렬화를 해야 겠죠.
    1
  • 조병장
    3k
    2013-07-02 20:09:45
    maker interface라고 하죠.
    maker interface에 대해 한번 검색해보면 되실거 같네요.
    0
  • Jason Wang
    12
    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) 를 갖기 때문에 역시 마찬가지로 오브젝트 타입의 참조값(결국 주소값)데이터 인스턴스를 직접 줄 수 없어서 직렬화된 데이터로의 교환을 주로 사용합니다.

    10
  • 로그인을 하시면 답변을 등록할 수 있습니다.