मैं एक आईपैड एप्लिकेशन पर काम करता हूं जिसमें सिंक प्रक्रिया होती है जो वेब सेवाओं और कोर डेटा को एक तंग लूप में उपयोग करती है। Apple's Recomendation के अनुसार स्मृति पदचिह्न को कम करने के लिए मैं आवधिक रूप से NSAutoreleasePool
आवंटित और निकालें। यह वर्तमान में बहुत अच्छा काम करता है और वर्तमान एप्लिकेशन के साथ कोई स्मृति समस्या नहीं है। हालांकि, मैं एआरसी में जाने की योजना बना रहा हूं जहां NSAutoreleasePool
अब मान्य नहीं है और इस तरह के प्रदर्शन को बनाए रखना चाहते हैं। मैंने कुछ उदाहरण बनाए और उन्हें समय दिया और मुझे आश्चर्य है कि एआरसी का उपयोग करके, एक ही तरह के प्रदर्शन को स्वीकार करने और कोड पठनीयता को बनाए रखने के लिए सबसे अच्छा तरीका क्या है।@autoreleasepool के साथ पीक मेमोरी उपयोग को कम करें
परीक्षण उद्देश्यों के लिए मैं 3 परिदृश्यों के साथ आया, प्रत्येक 1 और 10,000,000 के बीच एक संख्या का उपयोग कर एक स्ट्रिंग बनाते हैं। मैंने ऐप्पल एलएलवीएम 3.0 कंपाइलर (डब्ल्यू/ओ जीडीबी-ओ 0) और एक्सकोड 4.2 के साथ मैक 64 बिट एप्लिकेशन का उपयोग करके कितना समय लगाया, यह निर्धारित करने के लिए मैंने प्रत्येक उदाहरण को 3 बार चलाया। मैंने स्मृति के माध्यम से मोटे तौर पर क्या देखा, यह देखने के लिए उपकरणों के माध्यम से प्रत्येक उदाहरण भी चलाया।
उदाहरण नीचे निम्नलिखित कोड ब्लॉक के भीतर समाहित कर रहे हैं के प्रत्येक:
int main (int argc, const char * argv[])
{
@autoreleasepool {
NSDate *now = [NSDate date];
//Code Example ...
NSTimeInterval interval = [now timeIntervalSinceNow];
printf("Duration: %f\n", interval);
}
}
NSAutoreleasePool बैच [मूल पूर्व एआरसी] (पीक मेमोरी: ~ 116 KB)
static const NSUInteger BATCH_SIZE = 1500;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for(uint32_t count = 0; count < MAX_ALLOCATIONS; count++)
{
NSString *text = [NSString stringWithFormat:@"%u", count + 1U];
[text class];
if((count + 1) % BATCH_SIZE == 0)
{
[pool drain];
pool = [[NSAutoreleasePool alloc] init];
}
}
[pool drain];
रन टाइम्स:
10,928158
10,912849
11,084716
बाहरी @autoreleasepool (पीक मेमोरी: ~ 382 एमबी)
@autoreleasepool {
for(uint32_t count = 0; count < MAX_ALLOCATIONS; count++)
{
NSString *text = [NSString stringWithFormat:@"%u", count + 1U];
[text class];
}
}
भागो टाइम्स:
11,489350
11,310462
11,344662
इनर @autoreleasepool (पीक मेमोरी: ~ 61.2KB)
for(uint32_t count = 0; count < MAX_ALLOCATIONS; count++)
{
@autoreleasepool {
NSString *text = [NSString stringWithFormat:@"%u", count + 1U];
[text class];
}
}
भागो टाइम्स:
14.031112
14.284014
14।099625
डब्ल्यू @autoreleasepool/गोटो (पीक मेमोरी: ~ 115kb)
static const NSUInteger BATCH_SIZE = 1500;
uint32_t count = 0;
next_batch:
@autoreleasepool {
for(;count < MAX_ALLOCATIONS; count++)
{
NSString *text = [NSString stringWithFormat:@"%u", count + 1U];
[text class];
if((count + 1) % BATCH_SIZE == 0)
{
count++; //Increment count manually
goto next_batch;
}
}
}
भागो टाइम्स:
10,908756
10,960189
11,018382
goto
बयान निकटतम प्रदर्शन की पेशकश की, लेकिन यह एक goto
उपयोग करता है। कोई विचार?
अद्यतन:
नोट: goto
बयान के रूप में documentation में कहा गया है और स्मृति लीक नहीं होगा एक @autoreleasepool के लिए एक सामान्य निकास है।
प्रवेश पर, एक ऑटोरेलीज पूल धक्का दिया जाता है। सामान्य निकास पर (ब्रेक, रिटर्न, गोटो, फॉल-थ्रू, और इसी तरह) ऑटोरेलीज पूल पॉप हो गया है। मौजूदा कोड के साथ संगतता के लिए, अगर बाहर निकलने के कारण बाहर निकलें, ऑटोरेलीज पूल पॉप नहीं किया गया है।
अनुकूलक का उपयोग करें। एआरसी कोड के लिए यह महत्वपूर्ण है। –
ताकि 'गोटो' निश्चित रूप से नहीं है, मुझे नहीं पता, मेमोरी रिसाव का कारण बन रहा है? बाकी सब कुछ समझ में आता है: कम draining तेजी से है। वैसे भी, मैं केवल पठनीयता पर टिप्पणी कर सकता हूं: कहीं भी आप पूल ठीक है। उस गले को पीले चिपचिपा नोट की आवश्यकता होगी। –
गोटो किसी भी स्मृति को रिसाव नहीं लग रहा था। ऐसा लगता है कि स्कोप ने ऑटोरेलीज पूल को निकाला था जैसा कि मैंने उम्मीद की थी लेकिन मैं एआरसी (अभी तक) पर कोई विशेषज्ञ नहीं हूं और यूबी पर भरोसा नहीं करना चाहता हूं। – Joe