24

AFAIK trên Android, bạn nên tham khảo các đối tượng Bitmap như WeakReferences để tránh rò rỉ bộ nhớ. Khi không có tài liệu tham khảo cứng nhắc hơn được lưu giữ của một đối tượng bitmap, bộ thu gom rác sẽ tự động thu thập nó.Bitmap, Bitmap.recycle(), WeakReferences và Garbage Collection

Bây giờ, nếu tôi hiểu chính xác, phương thức Bitmap.recycle() phải luôn được gọi để giải phóng Bitmap. Tôi nghĩ rằng điều này là do các đối tượng Bitmap có quản lý bộ nhớ đặc biệt.

Điều đó có đúng không?

Nếu điều này đúng, khi sử dụng WeakReferences, phải có rò rỉ bộ nhớ vì Bitmap.recycle() không bao giờ được gọi khi WeakReferences được giải phóng. Hoặc bằng cách nào đó, có đủ yếu để tránh rò rỉ bộ nhớ không?

Cảm ơn

Trả lời

50

Bitamp.recycle không cần được gọi là, như các bộ thu rác sẽ dọn sạch bitmap ngày của riêng mình cuối cùng (miễn là không có tài liệu tham khảo). Các bitmap trong Android được tạo trong bộ nhớ riêng, không phải trên vùng máy ảo, do đó đối tượng Bitmap thực trên heap VM rất nhỏ vì nó không chứa bất kỳ dữ liệu bitmap thực tế nào. (EDIT: không còn là trường hợp của Android 3.0+) Kích thước thực của bitmap sẽ vẫn được tính dựa trên mức sử dụng heap của bạn cho mục đích của GC và đảm bảo ứng dụng của bạn không sử dụng quá nhiều bộ nhớ.

Tuy nhiên, GC có vẻ hơi thất thường khi nói đến Bitmap. Nếu bạn chỉ cần loại bỏ tất cả các tài liệu tham khảo khó, đôi khi nó (trong trường hợp của tôi) treo lên các Bitmap trong một thời gian dài hơn, có lẽ vì các đối tượng bitmap lạ được phân bổ/đếm. Bitmap.recycle có vẻ tốt cho việc GC thu thập đối tượng đó nhanh hơn.

Dù bằng cách nào, bạn sẽ không bị rò rỉ bộ nhớ nếu bạn không gọi Bitmap.recycle miễn là bạn không giữ tài liệu tham khảo cứng một cách vô tình. Bạn có thể gặp phải OutOfMemoryErrors nếu bạn cố gắng phân bổ quá nhiều bitmap cùng một lúc hoặc quá lớn bitmap mà không cần gọi .recycle, mặc dù.

EDIT: Điều quan trọng cần lưu ý là kể từ Android 3.0, Bitmap không còn được cấp phát trong bộ nhớ riêng. Các được phân bổ trên heap VM giống như bất kỳ đối tượng Java nào khác. Tuy nhiên, những gì tôi nói về việc không cần phải gọi tái chế vẫn được áp dụng.

+0

Giải thích đã xóa. Cảm ơn rất nhiều ! – Sly

+0

Tôi tải hình ảnh với khoảng 20 giây. Tôi gọi recycle() nhưng Debug.getNativeHeapAllocatedSize() cho thấy việc cấp phát bộ nhớ riêng liên tục phát triển cho đến khi OutOfMemoryError – Maxim

+0

đây là một bài đăng rất hay! – user123321

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