Memory leak trong Android, nguyên nhân và cách xử lý (phần 1)

Memory leak là gì?

Một ngày đẹp trời, app bạn đang chạy như ngựa băng băng qua cánh đồng trống, gió vi vu thì bỗng văng OutOfMemoryException. Bạn tự hỏi app mình không dùng quá nhiều bitmap, tại sao lại bị lỗi bộ nhớ? Tất nhiên, nếu app bạn dùng bitmap không tối ưu, bạn sẽ gặp vấn đề về bộ nhớ. Một nguyên nhân khác cũng dẫn đến hết tài nguyên bộ nhớ là app bị leak memory.

Vậy leak memory là gì? Hiểu đơn giản, leak memory xảy ra khi hệ thống không thể thu hồi vùng nhớ đã cấp phát cho đối tượng khi đối tượng không còn được sử dụng nữa. Ví dụ, bạn có một MainActivity, khi MainActivity được khởi chạy, bạn có một instance của MainActivity trong bộ nhớ. Khi user tắt MainActivity (onDestroy được gọi), Garbage Collector(GC) sẽ tiến hành thu hồi bộ nhớ của MainActivity. Đoạn code dưới đây sẽ làm cho activity không thể được thu dọn bởi GC.

Giờ thì chạy chương trình, ngay khi khởi chạy, bạn click phím back của device để tắt MainActivity đi, lúc này onDestroy sẽ được gọi nhưng MainActivity không được giải phóng. Vì sao? Vì thread vẫn còn đang chạy, anonymous class sẽ giữ một implicit reference tới outer class, nghĩa là thread đang chạy và đang sờ đến instance MainActivity của bạn do đó GC không thể thu hồi vùng nhớ của MainActivity.

Làm sao để biết là app bạn bị memory leak?

Đến đây bạn sẽ hỏi vì sao mình biết là MainActivity bị leak? Trả lời: Làm nhiều sẽ biết, sẽ rút ra kinh nghiệm. Chút nữa mình sẽ giới thiệu cho bạn một công cụ để phát hiện memory leak rất hiệu quả, giờ thì cho mình bàn một chút ngoài lề về đoạn code trên. Mình cho rằng đoạn code trên là đoạn code vô trách nhiệm. Vì tạo ra thread rồi start mà không quan tâm đến việc thread bao giờ sẽ kết thúc. Background thread đối với mình có hai loại, một loại im im mà làm không cần báo kết quả cho người dùng ví dụ như gọi api để tracking, một loại thì làm xong update UI ví dụ như download bitmap rồi hiện thị lên view. Loại im im thì nên dùng ThreadPool để quản lý, loại update UI thì nên dùng những cái được thiết kế sẵn như AsyncTask, không nên sản sinh thread tùy hứng như thế này. Appconus sẽ có một bài viết về cách quản lý thread hiệu quả trong Android, các bạn chờ xem nhé.

Quay lại vấn đề chính, đoạn code trên rất ngắn, rất dễ để phát hiện ra vấn đề nhưng nếu bạn có một activity 500 dòng code thì làm sao? Chỉ có một cách là đoán, nếu bạn nghi ngờ app của bạn bị memory leak bạn có thể đi vòng vòng trong app, qua những chỗ nghi ngờ bị leak, dump heap ra rồi dùng MAT (Memory Analyzer Tool – cái này có trong Android Device Monitor) để phân tích xem bị leak ở đâu. Đây là cách mà mình dùng trước đây. Còn bây giờ có một thư viện giúp bạn phát hiện leak cực kỳ hiệu quả, cài đặt chỉ một dòng code thôi, đó là LeakCanary(LC). Khi leak xảy ra, LC sẽ giúp bạn phân tích heap dump và thông báo bạn bị leak chỗ nào. Quá tuyệt đúng không?! Anh cứ lo nghiệp vụ, leak cứ để em(LC) lo.

Giờ mình sẽ dùng LC để xem nó phát hiện leak trong đoạn code trên như thế nào. Mình tiến hành cài LC như hướng dẫn:

Cài library

 

Cài trong application

Nhớ add MyApplication trong Manifest nhé.

Giờ thì chạy thôi. Bạn chạy MainActivity lên sau đó thoát đi, khoảng vài giây sẽ thấy một thông báo leak trên notification space, xem chi tiết thử nào:

Screen Shot 2015-08-16 at 9.29.45 PM

 

Yeah, phát hiện được leak rồi, giờ sao giải quyết? Mình để câu hỏi mở cho các bạn, cũng là mở cho mình, trong phần 2 mình sẽ đưa thêm những lỗi làm leak memory khác và những cách giải quyết cho từng loại. Kết thúc phần 1 tại đây. Cảm ơn!

Mời đọc phần 2 tại đây: http://blog.appconus.com/2015/08/23/memory-leak-trong-android-nguyen-nhan-va-cach-xu-ly-phan-2/

 

Spread the love
  • 9
  •  
  •  
  •  
  •  
    9
    Shares

Leave a Reply

5 Comments on "Memory leak trong Android, nguyên nhân và cách xử lý (phần 1)"

avatar
  Subscribe  
newest oldest most voted
Notify of
Anonymous
Guest

Bài viết của bạn rất hay.
Mình mong chờ bài viết về cách quản lý thread hiệu quả trong Android của bạn đấy.

Thanks.

Cao Quảng Bình
Admin

Vậy bạn đã subscribe chưa 🙂

Anonymous
Guest

Minh lam theo va test tren emulator thi ko thay thong bao gi ca