핸들바인딩
응용프로그램에서 타입과 타입 멤버들을 바인딩한 후 이 객체들을 컬렉션에 저장해두는 기법 사용 시 무분별(작은 타입들도 몽땅 저장)한 사용으로 메모리 낭비를 초래한다.
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 |