8

Tôi có một Hoạt động mà tôi thề là bộ nhớ bị rò rỉ. Các ứng dụng tôi đang làm việc trên rất nhiều với hình ảnh, vì vậy tôi đã có được khá keo kiệt với bộ nhớ khi làm việc trực tiếp với Bitmap. Tôi đã thêm một hoạt động, và bây giờ nếu bạn sử dụng hoạt động mới này về cơ bản đặt tôi trên cạnh với việc sử dụng mem và tôi kết thúc ném "Bitmap vượt quá ngân sách VM" ngoại lệ. Nếu bạn không bao giờ khởi chạy Hoạt động này, mọi thứ đều mượt mà như trước đây.Android - Rò rỉ bộ nhớ khi tự động xây dựng giao diện người dùng với nguồn tài nguyên hình ảnh

Tôi bắt đầu đọc về rò rỉ bộ nhớ và tôi nghĩ rằng tôi có tình huống tương tự với những gì được mô tả trong bài viết trong tài liệu Android. Tôi đang tạo động một loạt các lượt xem hình ảnh và thêm một BackgroundDrawable từ các tài nguyên và thêm một OnClickListener nữa. Tôi tưởng tượng tôi phải làm một số dọn dẹp khi Activity hits onPause trong vòng đời của nó, nhưng tôi muốn biết cụ thể cách nào là đúng.

Dưới đây là đoạn code mà phải chứng minh các đối tượng Tôi đang làm việc với ...

LinearLayout templateContainer; 
    . 
    . 
    . 
    ImageView imgTemplatePreview = (ImageView) item.findViewById(R.id.imgTemplatePreview); 
    . 
    . 
    . 
    imgTemplatePreview.setBackgroundDrawable(getResources().getDrawable(previewId)); 
    imgTemplatePreview.setOnClickListener(imgClick); 
    templateContainer.addView(item); 
+0

bạn đã tìm thấy bất kỳ thông tin nào khác về chủ đề này chưa? Tôi đang làm việc với một chế độ xem duy nhất lật hình ảnh sau khi nút được nhấp và sau nhiều lần khởi động lại ứng dụng, điều hiển nhiên là đang xảy ra đằng sau hậu trường vì tôi đã sử dụng phương thức unbind() và OOM vẫn còn trên tôi do kích thước bitmap vượt quá ... –

+0

Vâng ...điều này đã được đăng cách đây 7 tháng, và tôi đã đi một con đường dài với sự hiểu biết của tôi về Bitmap, bộ nhớ, lỗi OOM, vv Tìm email của tôi thông qua hồ sơ của tôi và tôi sẵn sàng thảo luận, vì đó là cách quá nhiều thông tin cho một bình luận chủ đề. Tóm lại, khi tôi thực sự đẩy các giới hạn, tôi viết một lớp quản lý các bitmap của tôi (trong một số trường hợp, nhiều lớp) và tôi tái chế mọi bitmap khi tôi sử dụng nó. Điều này có thể đơn giản như chỉ giữ một Bitmap duy nhất trong hoạt động của bạn và gọi .recycle trước khi thay thế nó bằng một cá thể mới. Tìm tôi nếu cần, tôi rất vui được thảo luận thêm. – Rich

+0

Hi Rich, tôi nhận ra tất cả chúng tôi đều bận rộn và chia sẻ kiến ​​thức cần có thời gian nhưng tôi cũng sẽ thực sự mô tả một số mô tả sâu sắc hơn về những gì bạn đã thu thập được trong 7 tháng này vì tôi vẫn còn ở tháng 2;) sẽ là bài viết thực sự phổ biến vì nó có vẻ là một câu hỏi tái diễn. Tôi đã đọc bài viết tuyệt vời của Romain nhưng điều đó dường như chỉ là gợi ý về những gì chúng ta cần biết về nguyên nhân gây rò rỉ khi xử lý bitmap ... cuộc gọi .recycle và onClick gây ra rò rỉ không được đề cập ở đó để chắc chắn có các mẹo khác & thủ thuật bị bỏ lỡ bởi công chúng. Cảm ơn, – sradforth

Trả lời

0

Điều này sẽ âm thanh một chút kỳ quặc, nhưng tôi đã gặp rắc rối với các ứng dụng mà đã làm bất kỳ thao tác bitmap trên một chủ đề khác với chuỗi được liên kết với Trình xử lý cho Hoạt động của bạn. Đặc biệt, tôi đã có một ứng dụng bị rò rỉ nhiều bộ nhớ bằng cách thực hiện thao tác hình ảnh trong một chuỗi java.util.Timer. Khi tôi di chuyển mã đó sang sử dụng Handler.postDelayed, các vấn đề về bộ nhớ sẽ tự xóa.

+0

Tôi nghe bạn, nhưng câu hỏi là nhiều hơn dọc theo dòng của những gì để làm với các đối tượng Android View cấp cao để tối đa hóa việc sử dụng bộ nhớ của họ và không bị rò rỉ ở đó. Tôi có một dãy mã thao tác hình ảnh đã hoạt động tốt. Có một giới hạn nhất định với những gì bạn có thể tải cùng một lúc, nhưng trong điều kiện làm việc bình thường, tôi đã tinh chỉnh rất nhiều thứ và nó hoạt động tốt. Ngay sau khi tôi giới thiệu những thứ được đề cập ở trên ... BOOM! – Rich

+0

Thật không may, tôi sợ tôi không có nhiều điều để cung cấp khác hơn là sự cảm thông. Tôi đã làm việc trên một vài ứng dụng có giao diện người dùng khá phức tạp và sau một thời điểm nhất định, chúng tôi chỉ đạt đến giới hạn của những gì mà BitmapFactory có thể xử lý và chúng tôi đã phải cân nhắc lại mọi thứ. Trên một ứng dụng, tôi đã phải nghỉ mát để làm một số phân trang để làm cho mọi thứ hoạt động cho ứng dụng của tôi và trong một ứng dụng khác, tôi phải giảm kích thước của một loạt các yếu tố đồ họa. – jjb

2

phong phú,

Nếu bạn đang đi để được làm việc với nhiều Bitmap s bạn tích cực nên làm sạch chúng khi chúng không cần thiết (là một khởi đầu tốt).

Tôi nhớ một cuộc thảo luận từ một thời gian dài trước đây về ImageView và hành vi kỳ quặc của chúng với các tham chiếu kéo dài tới bitmap được hiển thị của chúng. Từ những gì tôi nhớ lại là bạn nên loại bỏ tất cả các tham chiếu đến ngữ cảnh hiện tại từ ImageView nếu bạn định giữ cách bố trí còn sống nhưng không muốn bị rò rỉ. Xóa trình nghe bitmap và bitmap. Hãy gọi số .recycle() trên số Bitmap nếu bạn muốn bộ nhớ mạnh. Đảm bảo bạn không có bất kỳ trường tĩnh nào có tham chiếu kéo dài đến ngữ cảnh hoặc tham chiếu lớp bên trong đối với nó.

Mã cho trình khởi chạy của Android cũng được đề cập trong quá trình này làm tài liệu tham khảo tốt khi họ thực hiện một số việc này. OpenSource là bạn của bạn.

EDIT

Tìm thấy bài viết Romain Guys. Về cơ bản, anh ấy đề cập đến phần này theo cách mặc dù

Ví dụ này là một trong những trường hợp đơn giản nhất để làm rò rối bối cảnh và bạn có thể xem cách chúng tôi xử lý nó trong mã nguồn của màn hình chính (tìm phương pháp unbindDrawables()) bằng cách thiết lập các lệnh gọi lại có thể rút lại được lưu trữ thành vô hiệu khi hoạt động bị hủy.

Bây giờ tôi chưa bao giờ phải quản lý loại sử dụng bộ nhớ này (vì vậy) từ đây tôi đề nghị xem The Home Screen Source để biết thêm chi tiết. Bạn sẽ tìm thấy phương thức unbind() của mình trên dòng 620

+0

Vì vậy, đó là chính xác câu hỏi của tôi. Khi thêm một nền thông qua setBackgroundDrawable và OnClickListener thông qua setOnClickListener, cách thích hợp để dọn sạch các tài nguyên đó là gì. Tôi hiểu khái niệm mà tôi cần để làm sạch chúng, và bất kỳ Bitmap rõ ràng nào mà tôi khởi tạo trong mã của tôi đều đã được dọn sạch rồi. Câu hỏi đặt ra là - làm thế nào để tôi làm sạch công cụ gắn liền với một yếu tố giao diện người dùng có nguồn gốc View – Rich

+0

@Rich Tìm thấy bài viết tôi đã nghĩ đến khi viết câu trả lời này. Của nó bởi Romain Guy (Google Android Engineer) để một số công cụ thực sự tốt của nó. http://www.curious-creature.org/2008/12/18/avoid-memory-leaks-on-android/ – smith324

+0

Đối với những người quá laze để đọc toàn bộ điều, xem chỉnh sửa của tôi. – smith324

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