직렬화 serialization

C#/CLR via 2020. 3. 25. 08:19
반응형
 

Serialization-.NET

.NET의 SerializationSerialization in .NET 이 문서의 내용 --> serialization은 지속시키거나 전송할 수 있는 형태로 개체 상태를 변환하는 프로세스입니다.Serialization is the process of converting the state of an object into a form that can be persisted or transported. serialization과 짝을 이루는 것은 스트림을 개

docs.microsoft.com

 

핸들바인딩

응용프로그램에서 타입과 타입 멤버들을 바인딩한 후 이 객체들을 컬렉션에 저장해두는 기법 사용 시 무분별(작은 타입들도 몽땅 저장)한 사용으로 메모리 낭비를 초래한다.
RuntimeTypeHandle, RuntimeFieldHandle, RuntimeMethodHandle
세가지 형태의 핸들 타입은 모두 값형태이며, 단 하나의 IntPtr 타입 필드만을 가져 메모리로 상당히 자유로줘질 수 있음. 

직렬화 serialization

Serialization - 객체 그래프를 바이트스트림(byte stream) 으로 변환하는 과정


Deserialization - 
바이트스트림(byte stream)에서 역으로 객체 그래프로 변환하는 과정

장점

l  데이터 베이스에 손쉽게 저장 가능

l  클립보드에 손쉽게 복사 및 다른 응용프로그램에 붙여넣기 가능

l  원본 객체 복제해 백업 용돌 가질 수 있음

l  네트워크를 전송할 때 유용  앱도메인의 경계를 가로질러 객체를 전달

단점(부족한 점)

l  통신 프로토콜 고려

l  클라이언트/서버의 타입 불일치(리틀/빅 엔디안)

l  오류 처리 및 다른 객체를 참조하는 객체

l  In 혹은 out 매개 변수 처리

l  구조체 배열, 리스트 고려

l  스레드, 파일, 프로세스, 뮤텍스, 이벤트, 세마포어 등 핸들 값을 역직렬화 해봤자 동일 프로세스에만 의미가 있음

부족한 점은 .Net Framework에서 제공하는 기능으로 극복가능

XmlSerializer DataContractSerializer  클래스 사용해 직렬화, 역직렬화를 수행

[serializable] – 사용자 정의 특성으로 직렬화 실행 시 타입을 명시적으로 지정할 수 있도록 제공한다.

예를 들어 단순 struct Point { public int x, y } 라는 구조체 생성 후
Point pt = new Point;
using(var stream = new MemoryStream())
{ new BinaryFormatter().Serialize(stream, pt); }
식으로 연결 시 직렬화 부분에서 명시적인 Point 가 제공되지 않는다. 따라서
[serializable]
struct Point { public int x, y } 
식의 명시가 필요하다.
, 해당 사용자 특성은 상속이 불가능하다.

Serialize 작동방식

l  System.Runtime.Serializtion  FormatterServices 타입 구현

l  해당 포멧터는 GetSerializableMembers 메서드 호출
리플렉션으로 public, private 필드를 얻어온다. – MemberInfo 객체 배열 반환

l  Serialize 객체와 MemberInfo 객체들을 GetObjectData 메서드에 전달
객체 Object 배열형태로 반환, 이때 Object 배열의 0번째 값은 MemberInfo 0번째 항목이 가리키는 멤버의 값

l  어셈블리 구분자와 타입의 전체 이름을 스트림에 씀

l  두 배열을 순회하면서 멤버의 이름과 값을 스트림에 쓴다.

Deserialize 작동방식

l  스트림으로부터 어셈블리 구분자와 타입 전체 이름 읽음 GetTypeFromAssembly
System.Type 
객체 반환
앱도메인에 로드되어 있지 않다면 로드를 시도
어셈블리 로드 실패 시 SerializtionException 발생 후 중단.

l  Formatterservices  GetUninitializedObject 메서드 호출
새로운 객체를 위한 메모리만을 할당  생성자 호출 X + null이나 0으로 초기화

l  GetSerializableMembers 호출 + MemberInfo 배열을 생성 및 초기화

l  스트림 내에 포함된 데이터 이용 Object 배열 생성 초기화

FormatterServices 정적 메서드 PopulateObjectMembers 로 넘겨 멤버와 Object 배열을 순회하며 초기화한다.

 

ISerializeable 인터페이스

l  직렬화 과정을 사용자가 직접 제어한다.

l  특수 생성자(Special Constructor)를 같이 구현해야 한다.
반드시 호출해야 할 뿐아니라 자신의 하위 클래스와의 호환성을 유지하려면 인터페이스의 구현부를 절대 제거해서는 안 된다.

l  사용자 정의 특성을 무시하고 System.Runtime.Serialization.SerializationInfo 객체를 새롭게 생성해야한다.

반응형

'C# > CLR via' 카테고리의 다른 글

LINQ  (0) 2020.03.25
스레드(Thread)  (0) 2020.03.25
어셈블리 로딩과 리플렉션  (0) 2020.03.25
앱도메인  (0) 2020.03.25
가비지 컬렉터  (0) 2020.03.25
Posted by Lotus' Library
,