Việc tạo ra một ứng dụng Android thì rất đơn giản nhưng để tạo ra một ứng dụng mà chạy một cách mượt mà, sử dụng hiệu năng cũng như bộ nhớ tối ưu nhất thì không dễ chút nào. Với bản thân mình thì luôn thích tìm hiểu những cái mới mẻ, viết những hàm chức năng hay ho hay chỉ là thích tích hợp những thành phần UI cho là đẹp vào trong một ứng dụng. Để rồi tình trạng Memory Leak xảy ra, mình buộc phải tìm hiểu để giải quyết nó và nhận ra được tầm quan trọng của nó đối với ứng dụng như thế nào.


Memory Leak luôn là một vấn đề nan giải đối với nhiều lập trình viên. Thật sự, nó rất khó phát hiện ra cho đến khi xảy ra lỗi, bạn phải tốn thời gian để tìm hiểu vấn đề xảy ra ở đâu, lại lục lọi khắp nơi tìm cách sửa lỗi. Nhưng để rồi khi bạn hiểu được và nắm được nó thì rất dễ dàng cho bạn giải quyết Memory Leak.

Mình nhận thấy nhiều bạn cũng rất hay gặp tình trạng này giống mình. Dạo khắp StackOverflow thấy rất rất bài viết về Memory Leak. Nhưng tất cả điều bằng tiếng anh nên đôi khi cũng gây khó cho những bạn mới bắt đầu đọc hiểu và nắm được trọng tâm vấn đề. Hôm nay mình mình sẽ chia sẻ ngắn gọn nhất về nó. Thông tin cũng là mình gom nhặt và hệ thống lại để mọi người dễ hiểu.

Garbage Collector dọn rác bộ nhớ nhưng không hoàn toàn

Mình chủ yếu viết ứng dụng Android bằng JAVA. Cái tiện lợi nhất của JAVA là nó có bộ thu dọn rác tự động giúp mình, điều mình quan tâm là viết code những quản lí bộ nhớ thì đó thì cứ để JAVA lo thông qua Garbage Collector. 

Vậy vấn đề ở đây là tại sao có Garbage Collector rồi lại vẫn xảy ra tình rò rỉ bộ nhớ? 

Thật sự thì Garbage Collector vẫn làm đúng nhiệm vụ của nó nhưng đôi khi ứng dụng của chúng ta không cho phép nó dọn rác những phần bộ nhớ nhỏ xíu không dùng đến chỉ vì chúng ta bắt nó vậy. Chính những phần bộ nhớ nhỏ xíu ấy là nguyên nhân dần gây nên tình trạng rò rỉ dữ liệu.

Cách hoạt động của Garbage Collector

Theo như hình minh hoạ, bạn có thể thể phần trên cùng là phần mà bộ dọn rác (Garbage Collector) không thể dọn được và không có quyền tác động đến phần đó. Do đó, khi bạn càng sử dụng nhiều lên làm gia tăng phần bộ nhớ mà Bộ dọn rác không thể dọn đến vượt ngưỡng cho phép gây ra Rò rỉ dữ liệu.

Vậy Memory Leak là gì?

Memory Leak có thể nôm na là việc bạn giữ một đối tượng nào đó quá lâu thời gian cần nó để phục vụ cho tác vụ của bạn. Mỗi đối tượng đều có một vòng đời riêng của nó, khi hoàn tất vòng đời của nó thì sẽ được Garbage Collector dọn dẹp đi. Nhưng bạn vẫn giữ nó ở đó mãi dẫn đến tình trạng Memory Leak.

Hậu quả Memory Leak đem đến rất nhiều. Nếu nhẹ thì bạn sẽ thấy ứng dụng giật lag, khó thao tác hoặc thao tác chậm. Còn nặng hơn là ứng dụng bị crash (đóng đột ngột).

Tạo sao lại phải quan tâm đến Memory Leak?

Dù muốn dù không thì không một ai muốn sử dụng một ứng dụng nào là hết lag, chậm chạp, mới sử dụng một lúc thì lại đứng đơ ra đó không một phản hồi rồi lại đóng đột ngột. Đây thật sự mang đến một trải nghiệm người dùng thật sự tệ hại không ai mong muốn.

Sau một thời gian người dùng sử dụng ứng dụng tồn tại memory leak dẫn đến bộ nhớ HEAP sẽ gia tăng trong khi nó có hạn mà không được giải phóng đi. Khi đạt ngưỡng nó sẽ báo bạn lỗi OutOfMemoryError và crash ứng dụng của bạn ngay.

Garbage Collector là một tiến trình nặng nề nên bạn càng hạn chế sinh ra rác thừa thải, thì ứng dùng càng chạy tốt. Khi bộ nhớ heap tăng trước khi đạt ngưỡng thì Garbage Collector sẽ bắt đầu chạy để dọn những phần mà gọi là đối tượng chết (không còn được sử dụng nữa) để làm trống bộ nhớ heap đi, khi quá trình này diễn ra ứng dụng sẽ giật lag nhẹ. Nhưng nếu vấn đề rò rỉ bộ nhớ của bạn quá lớn thì sẽ giật lag rất nhiều đôi khi không thể sử dụng một lúc trước khi bình thường trở lại

Làm thể nào để nhận biết Memory Leak?

Thật may mắn là Android Studio cung cấp cho bạn một công cụ để kiểm tra quá trình ứng dụng chạy đã chiếm CPU, GPU và bộ nhớ bao nhiêu và nó chạy theo thời gian thực. Đó là Profile. Để chạy Profile bạn chọn Run > Profile .

AUTOMATING – OUTOFMEMORYERROR TROUBLESHOOTING – HeapHero – Java ...


Khi bạn đang sử dụng hay debug hãy để đến đồ thị sử dụng tài nguyên máy của ứng dụng.  Khi bạn thấy sự gia tăng độ ngột bộ nhớ mà không hề giảm đi thì khả năng ứng dụng của bạn đang rò rỉ bộ nhớ.

Profile của Android Studio

Allocation Tracker giúp bạn kiểm tra ứng dụng sử dụng tỷ lệ phần trăm bộ nhớ được phân bổ cho các loại đối tượng khác nhau trong ứng dụng của bạn. Bạn có thể thấy rõ ràng về những đối tượng chiếm nhiều bộ nhớ nhất và cần được giải quyết.

Mọi người thường khi xem đến Profile hầu như chỉ là xem qua đường. Không để ý quá nhiều đến nó và nó cũng thật sự cũng không cung cấp quá nhiều thông tin về chính xác chỗ nào gây nên tình trạng rò rỉ bộ nhớ của ứng dụng.

Thật may thay có một thư viện có thể giúp bạn biết chính xác vị trí gây nên tình trạng rò rỉ dữ liệu.

LeakCanary🐤  is a memory leak detection library for Android (thư viện nhận biết rò rỉ bộ nhớ cho Android).

Với những điều LeakCanary mang lại thông tin về các phần bên trong của Android Framework mang đến cho nó một khả năng duy nhất để thu hẹp nguyên nhân của mỗi rò rỉ, giúp các nhà phát triển giảm đáng kể các sự cố OutOfMemoryError.



Tóm lại

Mình rất xin lỗi không có nhiều thời gian để viết chi tiết hơn nhưng mong với những chia sẻ thông qua tìm hiểu trên đây sẽ giúp các bạn nắm được khái quát nguyên nhân cốt lõi gây nên vẫn đề rò rỉ dữ liệu. Từ đó, bạn có thể tìm hiểu thêm để giải quyết các vẫn đề bạn gặp phải. Mình sẽ cố gắng viết thêm một bài tổng hợp các trường hợp dễ gây nên vấn đề rò rỉ bộ nhớ nhất cho mọi người.

Trang blog của mình còn nhiều hạn chế nhưng mong các bạn hãy theo dõi nha. Nếu bạn có thắc mắc hay góp ý gì hãy để lại bình luận để mình cải thiện nha.

Post a Comment

Mới hơn Cũ hơn