[Android Performance] Leak Canary: Các tùy chọn nâng cao
Ở phần trước [Android Performance] Leak Canary: Công cụ check leak hiệu quả mình đã giới thiệu tới các bạn tác dụng, cách cài đặt và sử dụng của Leak Canary. Tuy nhiên, Leak Canary còn cung cấp cho chúng ta nhiều tùy chọn khác để việc phát hiện Memory Leak được đơn giản, chính xác và tiện hơn. Và trong bài viết này, mình sẽ giới thiệu tới các bạn một vài tùy chọn trong đó.
Trước khi bắt đầu bài viết này, các bạn nên chắc chắn là mình đã hiểu rõ về cách cài đặt và sử dụng Leak Canary, nếu chưa hãy đọc lại bài viết này nhé:
Như ở phần trước mình đã nói về cách cài đặt Leak Canary bằng cách gọi lệnh LeakCanary.install() trong Application của ứng dụng, tuy nhiên khi này Leak Canary sẽ chỉ phát hiện các leak đối với Activity mà thôi, còn đối với các thành phần như Fragment, hay các biến khác có thể gây Memory Leak nhưng không phải là đối với Activity thì Leak Canary sẽ không phát hiện được. Điều này không phải là giới hạn của Leak Canary mà là do đây là config mặc định của những người tạo ra Leak Canary. Vậy làm sao để Leak Canary có thể phát hiện được các dạng leak khác. Câu trả lời đó là hãy sử dụng RefWatcher để có thể theo dõi và phát hiện leak đối với bất kì một đối tượng nào trong ứng dụng của bạn.
I. Sử dụng RefWatcher
Mỗi khi bạn gọi lệnh LeakCanary.install() thì chính câu lệnh này sẽ trả về cho bạn 1 RefWatcher để tử đó bạn có thể sử dụng RefWatcher này và theo dõi các đối tượng khác trong ứng dụng của bạn. Vì vậy để sử dụng RefWatcher bạn hãy làm theo 3 bước dưới đây nhé:
Bước 1: Khai báo 1 đối tượng static RefWatcher trong Application class của bạn
Bước 2: Gán giá trị cho đối tượng này trong onCreate của Application khi gọi LeakCanary.install()
Bước 3: Sử dụng RefWatcher.watch() để theo dõi đối tượng của bạn.
Như vậy là bạn đã có thể thiết lập cho Leak Canary theo dõi các đối tượng khác mà bạn mong muốn rồi đó. Và chú ý khi bạn sử dụng RefWatcher thì Leak Canary vẫn sẽ theo dõi Memory Leak đối với các Activity của bạn như trong thiết lập mặc định chứ không phải là chỉ những đối tượng nào mà bạn đã đăng kí theo dõi với RefWatcher đâu nhé.
Sở dĩ có điều này là vì việc 1 Activity không được giải phóng là một hiện tượng cực kì nguy hiểm đối với bất kì 1 ứng dụng nào bới nếu Activity mà không được giải phóng thì bất cứ thứ gì dính liền với Activity đó như là Fragment, View, Thread, … cũng đều không được giải phóng, đó sẽ là 1 dung lượng khổng lồ tồn tại một cách vô ích. Và nếu Activity đó được sử dụng thường xuyên thì sẽ chẳng mấy mà ứng dụng của bạn bị force close bởi hệ thống đâu, lúc đó sẽ là 1 thảm hoạt đối với cả người dùng và chính các bạn nữa.
II. Cách thức hoạt động của RefWatcher
Chắc hẳn 1 số bạn sẽ thắc mắc về cách hoạt động Leak Canary và tại sao Leak Canary lại có thể đưa ra được chính xác nguyên nhân gây ra Memory Leak như vậy. Để giải đáp cho thắc mắc này và cũng là để chứng minh cho tính đúng đắn của kết quả mà Leak Canary đưa ra mình xin được trích dẫn cách hoạt động của Leak Canary (hay cũng là cách thức làm việc của RefWatcher) như sau:
- Khi được gọi,
RefWatcher.watch()
sẽ tạo ra 1 KeyedWeakReference to the watched object. - Sau đó, trong khi chạy ngầm Leak Canary sẽ kiểm tra xem các reference tới đối tượng này đã được xóa hết chưa (đối tượng đã được giải phóng chưa). Nếu chưa thì GC sẽ được gọi để thử giải phóng đối tượng.
- Nếu sau khi GC đã thực hiện xong mà đối tượng vẫn không được giải phóng (các reference vẫn chưa bị xóa hết) thì Leak Canary sẽ tiến hành việc lấy dump heap của ứng dụng dưới dạng file hprof.
- Tiếp theo đó
HeapAnalyzerService
sẽ được khởi động và tiến hành phân tích dump heap thu được ở bước trên bởi HeapAnalyzer. HeapAnalyzer
sẽ tìmKeyedWeakReference
của đối tượng (Reference chính gây ra leak) trong dump heapHeapAnalyzer
tính toán path ngắn nhất tới GC root(đường ngắn nhất nối từ đối tượng hiện tại tới GC root trong GC Map của ứng dụng) để tìm nguyên nhân gây leak đối với đối tượng đã đăng kí.- Kết quả được đưa tới
DisplayLeakService
và hiển thị thông báo cho người dùng.
Nhìn vào 7 bước bên trên bạn đã có thể thấy được cách thức hoạt động của Leak Canary rồi chứ và cũng nhờ cách thức hoạt động như vậy nên Leak Canary sẽ luôn hoạt động được chính xác và thậm chí trong nhiều trường hợp là quá nhạy (ví dụ như là với biến static chẳng hạn) nên bạn cũng đừng bao giờ lo lắng về việc Leak Canary báo sai nhé.
Và để thay cho kết thúc cho bài viết này, mình cũng muốn gửi tới các bạn 1 lời khuyên, hãy sử dụng Leak Canary với ứng dụng của các bạn, và hãy cố gắng giải quyết được tất cả các thông báo Leak Canary đưa ra chỉ trừ khi bạn không còn có cách nào khác để giải quyết vấn đề này thôi nhé.
Chúc ứng dụng của các bạn sẽ không bao giờ bị Memory Leak 🙂 .
- Google+
- Wordpress