Detect memory leaks in iPhone app

เรื่อง memory management ในภาษา Objective-C เป็นสิ่งที่น่าปวดหัวของโปรแกรมเมอร์สายตลาด (Java/C#) เมื่อมาจับสายอินดี้ใหม่ๆ – ต้อง alloc init, retain, release ในขณะที่เมื่อก่อน new ก็จบ ปล่อยให้ Garbage Collector จัดการให้เสร็จศัพท์

เวลาที่ release หรือ dealloc เพลินๆไปหน่อย จะเกิดอาการ exc_bad_access ทำให้ต้องแก้ปัญหาด้วย retain หรือไม่ยอม release ดื้อๆไปเลย – ซึ่งเป็นสาเหตุของ “เมมรั่ว” หรือ memory leaks นั่นเอง หากรั่วไม่เยอะเราก็อาจจะไม่รู้ตัว จนกระทั่งมัน crash ตอน user ใช้ไปนานๆนั่นแหละ

วิธีแก้ปัญหานี้มีสองแบบใหญ่ๆ คือใช้ LLVM/Clang Static Analyzer หรือใช้ Instruments app ของ Apple – วันนี้ผมจะพูดถึงอย่างหลังครับ

ตัวอย่างโค้ดที่มีเมมรั่ว

BOOL isFound = NO;
NSMutableArray *flattenDSTemp = [[NSMutableArray alloc] initWithArray:[_professionDSSectioned allValues]];
NSMutableArray *flattenDS = [[NSMutableArray alloc] init];
for (NSMutableArray *section in flattenDSTemp) {
	[flattenDS addObjectsFromArray:section];
}
for (NSMutableDictionary *row in flattenDS) {
	NSString *optionText = (NSString *)[row valueForKey:@"text"];
	if([optionText isEqualToString:user.profession]) {
		[row setValue:[NSNumber numberWithBool:YES] forKey:@"selected"];
		isFound = YES;
		break;
	}
}

วิธีใช้ Instruments ให้เลือกเมนู Run > Run with Performance Tool > Leaks

แล้ว app ของเราก็จะรันไปตามปรกติ พ่วงด้วยเจ้า Instruments หน้าตาแบบนี้

ในขณะที่เราเล่น app ไปเรื่อยๆ หากมีเมมรั่วมันจะโผล่มาตรง leaks

จากรูปจะเห็นว่าเราลืม release ไปสองที่ – แก้แล้วเป็นดังนี้

BOOL isFound = NO;
NSMutableArray *flattenDSTemp = [[NSMutableArray alloc] initWithArray:[_professionDSSectioned allValues]];
NSMutableArray *flattenDS = [[NSMutableArray alloc] init];
for (NSMutableArray *section in flattenDSTemp) {
	[flattenDS addObjectsFromArray:section];
}
[flattenDSTemp release];
for (NSMutableDictionary *row in flattenDS) {
	NSString *optionText = (NSString *)[row valueForKey:@"text"];
	if([optionText isEqualToString:user.profession]) {
		[row setValue:[NSNumber numberWithBool:YES] forKey:@"selected"];
		isFound = YES;
		break;
	}
}
[flattenDS release];

Compile แล้วรันด้วย Instruments ใหม่อีกครั้ง คราวนี้ไม่รั่วแล้วล่ะครับ :)

นอกจากตรวจเมมรั่ว เจ้า Instruments ยังทำได้อีกหลายอย่างเลยนะ ลองเล่นเปิด Library แล้วลากมาวางเล่นดูครับ

7 Comments

  1. จิ๋ว
    Posted July 18, 2010 at 8:25 pm | #

    พี่เต้ย เคยเจอ memory leak จาก library ของ Apple หรือเปล่า ครับ ไม่รู้จะแก้ยังไง
    แต่ ยังดีที่ submit แล้ว approve ผ่าน

  2. physician assistant
    Posted August 6, 2010 at 12:20 am | #

    Great information! I’ve been looking for something like this for a while now. Thanks!

  3. Posted August 12, 2010 at 12:42 am | #

    เคยเจอกับ NSURLConnection แบบ synchronous น่ะ ถ้าเป็น async จะไม่เป็นไร
    leak นิดหน่อยขำๆ พี่เองก็ไม่ค่อยได้เช็คหรอก เขียนปกติยังไม่ค่อยจะเสร็จทัน 555

    มาตอบช้าไปเกือบเดือน จิ๋วจะเห็นป่าวหว่า? แล้วเป็นยังไงบ้างเรา ตอนนี้ทำงานที่ไหนละ ไม่เจอที่ SWP เลย?

  4. Posted June 29, 2011 at 4:03 am | #

    Thank you for quality points there. I am kind of new to online Nice Post Thank you.

  5. Posted June 29, 2011 at 1:39 pm | #

    Thank you for quality points there. I will subscribe for your rss please keep posting

  6. Posted June 30, 2011 at 10:39 am | #

    Thank you for quality points there. I will subscribe for your website

  7. Posted August 27, 2011 at 10:23 pm | #

    Heckuva good job. I sure appraceite it.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>