7

Tôi đã dành gần một ngày để tìm hiểu lý do rò rỉ bộ nhớ trong Android. Có một hoạt động mà tôi mở/đóng nhiều lần (với bộ hẹn giờ). Sau một thời gian tôi đã nhận lỗi OutOfMemory:GC không nên chạy tự động trong Xamarin.Android trước khi hết bộ nhớ?

enter image description here

tôi thấy nhớ đi lên liên tục trong Xamarin Profiler mỗi khi hoạt động mở:

enter image description here

Tôi chắc chắn không có thuộc tính hoặc xử lý sự kiện có thể bị kẹt trong hoạt động đó. Tôi thậm chí đã xóa mọi hình ảnh, nút, v.v., cố gắng phát hiện những gì đã gây ra rò rỉ bộ nhớ. Vẫn như cũ ...

Sau đó, tôi đã thực hiện GC.Collect() trong phương thức hoạt động chính của OnResume (hoạt động mở ra hoạt động có vấn đề). Bây giờ tôi có thể thấy bộ nhớ đi lên và xuống như nó cần. Bạn có thể xem kết quả trong hình:

enter image description here

Theo Xamarin docs:

Các GC sẽ chạy khi đống nhỏ đã chạy ra khỏi bộ nhớ cho phân bổ mới

Nhưng điều đó không thực sự xảy ra

+3

đọc liên quan: https://developer.xamarin.com/guides/android/advanced_topics/garbage_collection/#Cross-VM_Object_Collections và http://stackoverflow.com/questions/ 28863058/xamarin-android-finalizer-không-get-gọi-khi-rời-the-hoạt động-to-go-to/28868582 # 28868582 – matthewrdev

Trả lời

9

Bạn có thể muốn đọc thêm một chút trong liên kết của mình trong Giúp GC: The GC has an incomplete view of the process and may not run when memory is low because the GC doesn't know that memory is low.Managed Callable Wrappers do not add additional instance members

Về cơ bản, nó sẽ xuất hiện BaseActivity là một Android Callable Wrapper (ACW) và Mono GC không biết lớn thế nào, vì vậy nó không biết để gọi bộ thu gom rác. Từ những gì tôi thu thập, ACW là một cách để triển khai các giao diện Android.

Giải pháp là, khi bạn phát hiện ra, để gọi thủ công bộ thu gom rác được đề xuất trong tài liệu Xamarin khi sử dụng ACW.

http://developer.xamarin.com/guides/android/advanced_topics/garbage_collection/

----

Kể từ khi niêm yết ban đầu của câu trả lời này, các tài liệu Xamarin đã được cải thiện trong lời giải thích của họ về tình trạng này:

Một thể hiện của một Java Loại .Lang.Object hoặc loại có nguồn gốc là có kích thước tối thiểu 20 byte. Trình bao bọc có thể gọi được quản lý không thêm cá thể bổ sung thành viên, vì vậy khi bạn có phiên bản Android.Graphics.Bitmap đề cập đến bộ nhớ 10MB, Xamarin.Android's GC sẽ không biết rằng - GC sẽ thấy 20 đối tượng byte và sẽ không thể xác định rằng đối tượng được liên kết với các đối tượng được phân bổ theo thời gian chạy Android đang giữ cho 10MB bộ nhớ còn sống.

Điều này cho thấy rằng, bất kể đối tượng được thiết lập để null hay không, bạn nên vẫn tay gọi Xamarin GC nếu bạn đang phân bổ/deallocating Máy đóng gói Callable có thể có khả năng tiêu thụ một lượng lớn ký ức.

Hoạt động theo giả định Java Object là 20 byte, nếu một được cấp phát và vô số 100 đối tượng tiêu thụ 10MB mỗi thẻ, Xamarin GC tin rằng 4000 byte bộ nhớ đang được sử dụng. Trong thực tế, ~ 1GB đang được sử dụng và GC có thể hoặc không thể được gọi.

-3

Gọi bộ sưu tập rác không đảm bảo rằng bộ sưu tập rác sẽ chạy hoặc tất cả các cấp phát bộ nhớ sẽ xuất hiện. Nhiều lần nó là về việc loại bỏ một tham chiếu đến một đối tượng. Nếu một đối tượng có một tham chiếu đến nó, nó sẽ không được thu gom rác. Tôi phải học cách này một cách khó khăn. Về cơ bản để khắc phục vấn đề này tại bất kỳ điểm nào bạn có thể null ra một đối tượng bất cứ lúc nào và chỉ cần đặt nó khi bạn cần. Ví dụ:

CustomObject cusObj = null; 
if (cusObj == null) 
{ 
    cusObj = new CustomObject(); 
} 

Chỉ đơn giản là đảm bảo bạn vô hiệu hóa đối tượng sẽ xóa tham chiếu. Nhưng như đã nêu trong câu trả lời ở trên, bạn có thể thu thập rác. Chỉ cần nhớ GC sẽ không thu thập rác một mục với một tham chiếu. Hãy xem tại địa chỉ:

Garbage collection and references C#

+0

Như bạn có thể đọc trong câu hỏi, nó không phải là một vấn đề tham khảo gây ra tôi đã chắc chắn để sạch mọi thứ – xleon

+0

Không đúng nguyên nhân lớn nhất của lỗi không gian heap là tham chiếu đến các đối tượng mà sẽ không cho phép các bộ thu rác để làm công việc đó. – yams

+0

Nulling ra các đối tượng của bạn để thoát khỏi các tài liệu tham khảo sẽ có được thoát khỏi vấn đề ở nơi đầu tiên. – yams

Các vấn đề liên quan