5

클라이언트에 직렬화 된 일부 큰 개체 (~ 115Mb)를 보내는 .NET 4 WCF 서비스가 있습니다. 객체가 처음으로 들어 오면 잘 디시 리얼 라이즈됩니다. 그러나 이후의 모든 호출은 OutOfMemoryException을 던집니다. 내 모든 IDisposablesusing 블록으로 싸여 있는지 확인했습니다. 나는 이것과 비슷한 다른 질문 인 BinaryFormatter outofmemory exception deserialization Deserialize from MemoryStream throws OutOfMemory exception in C# 을 보았다. 나는 Simon Hewitt's Optimized Serializer을 사용하는 것을 포함하여 사람들이 추천 한 해결책 중 일부를 시도했다. 그러나 결국 그는 객체 직렬화를 위해 여전히 BinaryFormatter에 의존합니다.내부 StringBuilder 호출에서 오는 BinaryFormatter.Deserialize의 OutOfMemory 예외

나는 OutOfMemoryException을 잡았고 스택 추적을 보았습니다 (아래 참조). 추적 코드는 StringBuilder 클래스의 메모리 사용 문제로 인해 나타납니다. 더 많은 공간이 필요할 때 사용하는 (길이 * 2) 알고리즘으로 인해 StringBuilder이 메모리 문제를 일으킬 수있는 다른 기사를 읽었습니다.

at System.Text.StringBuilder.ToString()  
at System.IO.BinaryReader.ReadString()  
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectString(BinaryHeaderEnum binaryHeaderEnum)  
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()  
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)  
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)  
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream) 

다르게 작동 및 StringBuilder를 사용하거나 더 나은 메모리를 관리 BinaryFormatter 좋은 대안이 존재하지 BinaryFormatter을 얻을 수있는 방법이 있나요?

+0

첫 번째 호출에서도 같은 크기의 객체였습니까? 혹시라도 코드를 게시 할 수 있습니까? –

+0

예, 두 경우 모두 정확히 동일한 응답이었습니다. 나는 정확한 바이트 크기를 매번 확인했다. 내가 코드를 풀어 낼 수 있는지 알 겠지만 꽤 길다. – MrWuf

답변

1

크기에 상관없이 BinaryFormatter를 사용하지 않는 것이 좋습니다 (실제로는 binaryformatter를 사용하지 않는 경우 크기가 더 작을 수 있습니다). 표 형식의 데이터와 같은 단순한 데이터이거나 순환 참조가없는 것과 같은 몇 가지 제약이있는 경우 간단한 이진 작성기로 자신의 이진 직렬화를 수행하거나 protobuf-net 또는 json.net과 같은 선반 직렬 변환기를 사용하면 크기가 더 작고 상당히 빠릅니다.