2014-10-13 27 views
6

Trong khi thay đổi kích thước các bitmap lớn để tải lên hình ảnh nhanh hơn lên máy chủ, tôi thỉnh thoảng chạy vào OutOfMemoryErrors. Để ngăn chặn điều này, tôi tính toán số lượng bộ nhớ cần thiết và kiểm tra xem nó có vượt quá Runtime.getRuntime(). MaxMemory() trước khi cố gắng mở rộng một hình ảnh.Heap không mở rộng trên trình giả lập Genymotion

Tuy nhiên, tôi vẫn gặp lỗi OOM mặc dù hình ảnh phải vừa với heap dễ dàng.

Thiết bị mô phỏng (Galaxy SII API 16) cho tôi bộ nhớ tối đa 67108864 byte bằng phương pháp trên.

Trong đoạn mã sau, kích thước heap là 43975K và chỉ < 15K bộ nhớ đó đang được sử dụng. Đối với việc phân bổ ~ 31K của tôi, vùng heap sẽ tự động tăng lên khoảng 45K mà vẫn không gần với kích thước tối đa 64 MiB. Nhưng như bạn có thể thấy, thay vì mở rộng heap, valvik vm hết bộ nhớ.

10-13 20:35:57.223: D/dalvikvm(1201): GC_FOR_ALLOC freed 505K, 67% free 14692K/43975K, paused 31ms, total 31ms 
10-13 20:35:57.223: I/dalvikvm-heap(1201): Forcing collection of SoftReferences for 31961100-byte allocation 
10-13 20:35:57.251: D/dalvikvm(1201): GC_BEFORE_OOM freed 2K, 67% free 14689K/43975K, paused 29ms, total 29ms 
10-13 20:35:57.251: E/dalvikvm-heap(1201): Out of memory on a 31961100-byte allocation. 

Tôi tự hỏi liệu điều này có thể xảy ra trên thiết bị thực hay nếu đây có thể là lỗi về gen.

Heap có được đảm bảo mở rộng tối đa maxMemory() không? JavaDoc cho Runtime.getRuntime(). FreeMemory() nói rằng "có thể" mở rộng, điều đó có nghĩa là gì.

Tôi chỉ cần một cách đáng tin cậy để tính toán dung lượng bộ nhớ Tôi có thể sử dụng, đây là cách tôi đã làm nó, hãy sửa lại cho tôi nếu tôi sai:

long maxMemory = Runtime.getRuntime().maxMemory(); 
long usedMemory = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); 
long availableMemory = maxMemory - usedMemory; 

gọi này làm cho OutOfMemoryError:

// outOptions has an appropriate inSampleSize 
BitmapFactory.decodeStream(inputStream, null, outOptions); 
+0

Bạn đã giải quyết được sự cố này chưa? – KinGPinG

+0

Thật không may là không. Bất kỳ ý tưởng? – wkarl

+0

Không, tôi xin lỗi tôi vẫn đang xử lý nó. Tôi sẽ cho bạn biết nếu tôi tìm thấy một cái gì đó hữu ích. – KinGPinG

Trả lời

5

Out of memory on a 31961100-byte allocation

bitmap của bạn là 32M. VM không thể phân bổ không gian tuyến tính 32M để lưu trữ bitmap. Heap bị phân mảnh, vì vậy ngay cả khi heap của bạn có 32M không gian trống thì không phải lúc nào cũng có thể phân bổ không gian tuyến tính như vậy. Bạn có thể thử giải phóng bộ nhớ càng nhiều càng tốt và gọi GC trước khi giải mã luồng.

Cố gắng giải mã bitmap của bạn ở nhiều hơn effective way. Or process image in parts. Nếu bạn cho chúng tôi biết lý do bạn cần hình ảnh này, chúng tôi có thể cho bạn biết cách xử lý nó.

+0

Tôi đã giải mã bitmap với một inSampleSize> 1. Xử lý hình ảnh trong các phần có thể không phải là một tùy chọn - ngay cả khi tôi có thể lưu nó ở các phần mà tôi mong đợi sẽ có hiện vật khi ghép lại với nhau (đúng nếu tôi sai). Những gì tôi hiện đang làm là chia tỷ lệ hình ảnh xuống độ dài tối đa là 1920px trước khi tải lên máy chủ. – wkarl

+0

Có cách nào để tìm không gian tiếp giáp tối đa có sẵn để phân bổ không? – wkarl

+2

Không. Kiểm tra câu trả lời này: http://stackoverflow.com/questions/3331527/android-resize-a-large-bitmap-file-to-scaled-output-file Bạn cũng có thể tạo quy trình riêng để chia tỷ lệ hình ảnh tại đó, nó sẽ có cùng kích thước heap chỉ để xử lý hình ảnh. Hãy thử bật tùy chọn userLargeHeap trong tệp kê khai. Hoặc tải lên hình ảnh gốc bằng cách sử dụng luồng và chia tỷ lệ hình ảnh ở phía máy chủ. – Leonidos

1

Bạn có một đống 42MB, trong đó có 14MB đã được sử dụng, 67% (28m) là miễn phí/có sẵn

D/dalvikvm(1201): GC_BEFORE_OOM freed 2K, 67% free 14689K/43975K, paused ... 
    E/dalvikvm-heap(1201): Out of memory on a 31961100-byte allocation. 

Bạn đang cố gắng phân bổ ~ 31M (không phải 31K), lớn hơn 28M có sẵn, dẫn đến OOM.

Để biết chi tiết về giải thích dalvikvm memory allocation log message take a look at debugging memory

Có rất nhiều cách sử dụng bộ nhớ chia sẻ diễn ra trong android, đúng tính toán cho mỗi quá trình sử dụng bộ nhớ refer this SO question

Android best practices on efficient bitmap memory management có thể giúp đỡ

+0

42MB là kích thước hiện tại của vùng, Runtime.getRuntime(). MaxMemory() mang lại cho tôi 64 megabyte. Tôi đã có ấn tượng rằng tôi có thể sử dụng lên đến 64 megabyte và heap sẽ mở rộng lên đến kích thước đó. Bài đăng StackOverflow thú vị nhưng nó không thực sự trả lời câu hỏi làm thế nào để tính toán đáng tin cậy bao nhiêu bộ nhớ tôi có thể phân bổ một cách an toàn. – wkarl

1

Một điều bạn có thể thử tinh chỉnh là build.props tệp của ROM.

On Genymotion giả lập bạn có thể thử thực hiện những điều sau đây qua vỏ rễ:

cat /system/build.prop | grep dalvik 

và nó sẽ hiển thị phù hợp với các thiết lập Dalvik:

dalvik.vm.heapsize=256m 
dalvik.vm.lockprof.threshold=500 
dalvik.vm.stack-trace-file=/data/anr/traces.txt 

maxmemory cũng đang được báo cáo là 268.435.456 byte trên trình mô phỏng tôi đã thử nghiệm.

Vì vậy, bạn có thể thử phát bằng cài đặt này. Ngoài ra, đảm bảo rằng bộ nhớ được cấp phát trong cài đặt của VirtualBox tương thích với các giá trị này.

+1

Tôi thực sự không quan tâm đến trình mô phỏng. Tôi chỉ tự hỏi liệu điều tương tự có thể xảy ra với các thiết bị của người dùng thực sự ở ngoài không. – wkarl

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