के साथ मेमोरी उपयोग क्रमबद्ध छिद्रित बाइट सरणी हमारे आवेदन में हमारे पास कुछ डेटा संरचनाएं हैं जिनमें अन्य चीजों के अलावा बाइट्स की एक खंडित सूची होती है (वर्तमान में List<byte[]>
के रूप में उजागर)। हम बाइट्स को तोड़ते हैं क्योंकि अगर हम बाइट एरे को बड़े ऑब्जेक्ट ढेर पर डाल देते हैं तो समय के साथ हम स्मृति विखंडन से पीड़ित होते हैं।प्रोटोबफ-नेट
हमने अपने स्वयं के जेनरेट किए गए क्रमिकरण डीएलएल का उपयोग करके इन संरचनाओं को क्रमबद्ध करने के लिए प्रोटोबफ-नेट का उपयोग करना भी शुरू कर दिया है।
हालांकि हमने देखा है कि प्रोटोबफ-नेट धारावाहिक करते समय बहुत बड़े मेमोरी बफर बना रहा है। स्रोत कोड के माध्यम से देखकर ऐसा प्रतीत होता है कि शायद यह List<byte[]>
संरचना को लिखा गया है, जब तक यह बफर के सामने कुल लंबाई लिखने की आवश्यकता नहीं है, तब तक यह अपने आंतरिक बफर को फ्लश नहीं कर सकता है।
दुर्भाग्यवश दुर्भाग्यवश बाइट्स को पहले स्थान पर जोड़ने के साथ हमारे काम को कम कर देता है, और अंततः हमें स्मृति विखंडन के कारण आउटऑफमेमरी अपवाद देता है (उस समय अपवाद होता है जहां प्रोटोबफ-नेट बफर को 84k से अधिक करने का प्रयास कर रहा है, जो स्पष्ट रूप से इसे LOH पर रखता है, और हमारी समग्र प्रक्रिया मेमोरी उपयोग काफी कम है)।
यदि प्रोटोबफ-नेट कैसे काम कर रहा है, तो मेरा विश्लेषण सही है, क्या इस मुद्दे के आसपास कोई तरीका है?
अद्यतन
मार्क के जवाब के आधार पर, यहाँ मैं क्या कोशिश की है है:
[ProtoContract]
[ProtoInclude(1, typeof(A), DataFormat = DataFormat.Group)]
public class ABase
{
}
[ProtoContract]
public class A : ABase
{
[ProtoMember(1, DataFormat = DataFormat.Group)]
public B B
{
get;
set;
}
}
[ProtoContract]
public class B
{
[ProtoMember(1, DataFormat = DataFormat.Group)]
public List<byte[]> Data
{
get;
set;
}
}
तो यह क्रमानुसार करने:
var a = new A();
var b = new B();
a.B = b;
b.Data = new List<byte[]>
{
Enumerable.Range(0, 1999).Select(v => (byte)v).ToArray(),
Enumerable.Range(2000, 3999).Select(v => (byte)v).ToArray(),
};
var stream = new MemoryStream();
Serializer.Serialize(stream, a);
लेकिन अगर मैं छड़ी ProtoWriter.WriteBytes()
में ब्रेकपॉइंट जहां यहपर कॉल करता है विधि के निचले भाग की ओरऔर चरण DemandSpace()
में, मैं देख सकता हूं कि बफर फ़्लश नहीं किया जा रहा है क्योंकि writer.flushLock
1
के बराबर है।
अगर मैं इस तरह अपमानित करना के लिए एक और आधार वर्ग बनाने के लिए:
[ProtoContract]
[ProtoInclude(1, typeof(ABase), DataFormat = DataFormat.Group)]
public class ABaseBase
{
}
[ProtoContract]
[ProtoInclude(1, typeof(A), DataFormat = DataFormat.Group)]
public class ABase : ABaseBase
{
}
फिर writer.flushLock
DemandSpace()
में 2
बराबर होती है।
मुझे लगता है कि व्युत्पन्न प्रकारों के साथ यहां एक स्पष्ट कदम है जिसे मैंने याद किया है?
त्वरित उत्तर के लिए धन्यवाद। हमारी डेटा संरचना के बारे में आपका अनुमान सही था। क्या मैं यह कहने में सही कहूंगा कि हमें डेटाफॉर्मेट को किसी भी संदर्भ के लिए समूह में बदलने की आवश्यकता है जिसमें ए के संदर्भ भी शामिल हैं, और इसलिए ऑब्जेक्ट ग्राफ़ की जड़ तक? और इस परिवर्तन को भी प्रासंगिक ProtoInclude विशेषताओं पर भी होना चाहिए? –
@ जेम्स अनिवार्य रूप से, हां। हमम ... शायद मुझे इसके लिए एक मॉडल-स्तर डिफ़ॉल्ट जोड़ना चाहिए! –
मैंने समस्या को हल करने के लिए DataFormat.Group का उपयोग करने के अपने प्रयास के साथ अपना प्रश्न अपडेट कर दिया है, लेकिन मुझे अभी भी बफर को फ्लश करने में समस्याएं आ रही हैं। क्षमा करें अगर मैं मूर्ख हूँ .. –