2010-09-29 36 views
7

Tôi có một ứng dụng ở đây có tính năng hiển thị POI trên bản đồ. Nó chỉ là một POI và nó chỉ được vẽ khi nó thực sự nằm trong vùng màn hình hiển thị. Nó hoạt động hoàn hảo trong một thời gian nhưng nếu tôi chơi xung quanh phóng to và thu nhỏ và kéo, nó cuối cùng sẽ sụp đổ. Theo Logcat, lý do luôn là lỗi OutOfMemory.Lỗi bộ nhớ khi sử dụng API Google Maps

Lúc đầu, tôi nghĩ đó là lỗi trên API Google Maps. Sau khi một số nghiên cứu và nhìn thấy một số bài viết Romain Guy, tôi đã được loại thuyết phục rằng tôi đã làm một cái gì đó ngu ngốc trên ứng dụng của tôi mà giữ cho tôi chạy ra khỏi bộ nhớ theo thời gian. Sau đó, tôi chạy một số bài kiểm tra chi tiết hơn với Heap Analyzer (Eclipse) và tôi thấy rằng mặc dù tôi có 2+, đôi khi còn hơn 3 megabyte bộ nhớ trống, tôi vẫn nhận được những thông báo Force Close gây phiền nhiễu do OutOfMemoryError gây ra. Hầu hết các lần nó gặp sự cố khi cố gắng phân bổ một số bộ nhớ 614kb bất kể tôi đã bỏ bao nhiêu.

Sự cố này xảy ra rất nhiều trên Nexus One 2.2.1 và trên HTC Evo 2.1. Sau một vài thử nghiệm nhỏ, tôi không gặp sự cố nào trên G1 1.6 cũng như Samsung Galaxy S i9000 2.1. Nhưng tôi không thể nói chắc chắn G1 và Galaxy sẽ không hiển thị vấn đề này sau khi thử nghiệm thêm.

Tôi chỉ có thể nghĩ đến vấn đề phân mảnh bộ nhớ. Tôi hy vọng vấn đề này có một giải pháp. Tôi cũng sẽ rất vui nếu tôi chỉ có thể bắt lỗi này và ngăn ứng dụng bị lỗi.

Nếu nó giúp, đây là logcat:

09-29 08:58:06.661: ERROR/dalvikvm-heap(1552): 648000-byte external allocation too large for this process. 
09-29 08:58:06.661: ERROR/dalvikvm(1552): Out of memory: Heap Size=9991KB, Allocated=6980KB, Bitmap Size=14510KB 
09-29 08:58:06.661: ERROR/(1552): VM won't let us allocate 648000 bytes 
09-29 08:58:06.672: DEBUG/AndroidRuntime(1552): Shutting down VM 
09-29 08:58:06.672: WARN/dalvikvm(1552): threadid=3: thread exiting with uncaught exception (group=0x4001b390) 
09-29 08:58:06.672: ERROR/AndroidRuntime(1552): Uncaught handler: thread main exiting due to uncaught exception 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.graphics.Bitmap.nativeCreate(Native Method) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.graphics.Bitmap.createBitmap(Bitmap.java:569) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.google.android.maps.ZoomHelper.createSnapshot(ZoomHelper.java:422) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.google.android.maps.ZoomHelper.beginZoom(ZoomHelper.java:186) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.google.android.maps.MapView$2.onScaleBegin(MapView.java:371) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.view.ScaleGestureDetector.onTouchEvent(ScaleGestureDetector.java:208) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.google.android.maps.MapView.onTouchEvent(MapView.java:646) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.view.View.dispatchTouchEvent(View.java:3709) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:874) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:924) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:924) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:924) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1701) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1116) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.app.Activity.dispatchTouchEvent(Activity.java:2068) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1685) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1708) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.os.Handler.dispatchMessage(Handler.java:99) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.os.Looper.loop(Looper.java:123) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.app.ActivityThread.main(ActivityThread.java:4595) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at java.lang.reflect.Method.invokeNative(Native Method) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at java.lang.reflect.Method.invoke(Method.java:521) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at dalvik.system.NativeStart.main(Native Method) 
+0

Tôi nhận được các báo cáo lỗi tương tự từ người dùng của tôi có OS phiên bản 1.5, 2.1 và 2.2. Stacktrace không đi qua mã của tôi vì vậy tôi không thể bắt lỗi này - ứng dụng kết thúc với FC. – tomash

+0

Nó thực sự trông giống như một vấn đề phân mảnh.Nó giống như ứng dụng của tôi có một số rò rỉ bộ nhớ mà lây lan khối nhỏ dữ liệu trên tất cả các vùng bộ nhớ heap của tôi. Tôi đoán rằng kiểu hành vi này có thể được cải thiện trong các phiên bản tiếp theo của Dalvik vì nó có thể không phải là lỗi nhưng chắc chắn nó không phải là 'hành vi tốt' vì bạn thực sự có bộ nhớ nhưng hệ thống không thể sử dụng vì phân mảnh của nó. Vâng, tôi sẽ tiếp tục cố gắng để xem những gì có thể được thực hiện về nó. –

+0

Tôi biết đã hơn một năm kể từ khi câu hỏi này được hỏi nhưng có một giải pháp đang được phát triển cho vấn đề này? Tôi là curiuos. Cảm ơn trước! – Ahmed

Trả lời

1

Tôi đã chạy vào vấn đề này và tắt trong tháng qua. Cách tôi đã làm việc xung quanh vấn đề trong mã của tôi là bằng cách buộc GC để làm sạch bitmap không được quan tâm mà tôi đã gói trong WeakReferences. Cách tiếp cận này có thể không hiệu quả với bạn vì sự cố mà bạn đã dán ở trên dường như bắt nguồn từ MapView. Bất kể, cố gắng rắc một số lệnh System.gc() vào các vị trí chính trong mã của bạn và xem Nhật ký hệ thống để xem liệu các thông báo GC_EXPLICIT có cho biết rất nhiều đối tượng/byte được giải phóng hay không. Trong mã tôi đang làm việc trên tôi đã phải thêm một System.gc() vào cuối của phương pháp Adapter.getView() của tôi để đảm bảo rằng bitmap không sử dụng được làm sạch lên trong thời gian tới getView() được gọi. Cách tiếp cận này dường như đã làm giảm đáng kể hoạt động của tôi với kích thước bitmap 0.đáng sợ java.lang.OutOfMemoryError: bitmap vượt quá sự cố ngân sách VM.

+0

gọi System.gc() không nên giúp OOME. VM sẽ không thông qua OOME trước khi đầu tiên cố gắng chạy chính GC. Ngoài ra, System.gc() không có gì để phân mảnh. –

+0

Những lỗi OOME có xu hướng xảy ra thường xuyên hơn trên điện thoại của gia đình Galaxy như: Nexus One và Nexus S. Tôi không sử dụng Galaxy Nexus để kiểm tra xem sự cố này có xảy ra nhiều hơn trên điện thoại này hay không. Ném các cuộc gọi GC để dọn dẹp bộ nhớ cùng với mã hóa cẩn thận, theo như tôi biết, cách tốt nhất để tránh vấn đề này. Người ta cũng có thể bắt ngoại lệ (như là một Throwable) và ít nhất là ngăn chặn các ứng dụng từ lực lượng đóng cửa. Nhưng thật không may, tôi không chắc chắn nếu có một giải pháp dứt khoát cho vấn đề này ... –

1

Tôi đã gặp vấn đề tương tự CHÍNH XÁC này, tôi đã đọc mã bằng một số cuộc gọi System.GC và dường như nó có ích một chút, nhưng điều này vẫn xảy ra.

Tôi cũng đang gặp phải một vấn đề khác có thể liên quan đến nơi bản đồ dường như bị lật ra và ngẫu nhiên khi bạn phóng to thu nhỏ. Điều này có xu hướng xảy ra đôi khi trước khi xảy ra sự cố.

Đây là tất cả chỉ xảy ra trên HTC Desire mà tôi tin là điện thoại giống như Nexus One dưới mui xe. (và tương tự trong nhiều cách để EVO cũng bị nó).

Lưu ý: Nó hoạt động tốt 100% trên trình giả lập Arc-S, Galaxy V1, AVD và máy tính bảng Asus.

1

tôi đã cùng một vấn đề, hãy thêm dòng sau trong file manifest dưới thẻ ứng dụng

android: largeHeap = true. Điều này làm việc cho tôi

+0

nó cải thiện tỷ lệ tai nạn nhưng không giải quyết vấn đề hoàn toàn. –

+0

Điều này về cơ bản là một giải pháp sao lưu nếu hoàn toàn không có gì làm việc cả. –

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