我正在开发一个Android应用程序,要求我从服务器获取一些图像,以便在用户请求弹出窗口时以可滚动的弹出窗口显示它,我正在尝试获取所有图像使用universalImageLoader并将它们存储为Bitmaps
但是在获取图像时以及在我获得所有图像之后,我无限地显示GC_FOR_ALLOC
行,并且在按下显示的按钮时pop_up,pop_up正常显示但是当我开始向下滚动我的应用程序崩溃时,我收到了以下日志消息:
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): [ 03-09 08:57:40.758 107: 107 I/DEBUG ]
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): Build fingerprint: 'generic/vbox86tp/vbox86tp:4.3/JLS36G/eng.buildbot.20140128.092034:userdebug/test-keys'
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): [ 03-09 08:57:40.758 107: 107 I/DEBUG ]
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): Revision: '0'
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): [ 03-09 08:57:40.758 107: 107 I/DEBUG ]
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): pid: 2269, tid: 2269, name: xample.solaceap >>> com.example.solaceap <<<
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): [ 03-09 08:57:40.758 107: 107 I/DEBUG ]
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 97808030
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): [ 03-09 08:57:40.898 107: 107 I/DEBUG ]
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): eax 00000000 ebx b757b6ff ecx 0000000a edx 9780803a
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): [ 03-09 08:57:40.898 107: 107 I/DEBUG ]
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): esi 00000008 edi 00000001
.
.
.
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): channel '5284e038 com.example.solaceap/com.example.solaceap.Login (server)' ~ Consumer closed input channel or an error occurred. events=0x9
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): [ 03-09 08:57:41.014 479: 518 E/InputDispatcher ]
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): channel '5284e038 com.example.solaceap/com.example.solaceap.Login (server)' ~ Channel is unrecoverably broken and will be disposed!
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): [ 03-09 08:57:41.022 479: 518 W/InputDispatcher ]
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): channel '528b7508 PopupWindow:52a6ec40 (server)' ~ Channel is unrecoverably broken and will be disposed!
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): Grow heap (frag case) to 6.773MB for 196620-byte allocation
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): GC_FOR_ALLOC freed 7K, 27% free 6864K/9292K, paused 14ms, total 14ms
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): Attempted to unregister already unregistered input channel '5287e6f8 com.example.solaceap/com.example.solaceap.MainPage (server)'
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): Process com.example.solaceap (pid 2269) has died.
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): WIN DEATH: Window{528afe84 u0 com.example.solaceap/com.example.solaceap.Media}
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): Attempted to unregister already unregistered input channel '528afe84 com.example.solaceap/com.example.solaceap.Media (server)'
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): Force-removing child win Window{528b7508 u0 PopupWindow:52a6ec40} from container Window{528afe84 u0 com.example.solaceap/com.example.solaceap.Media}
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): Failed looking up window
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): java.lang.IllegalArgumentException: Requested window android.os.BinderProxy@5281f9fc does not exist
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7630)
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7621)
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): at com.android.server.wm.WindowState$DeathRecipient.binderDied(WindowState.java:1000)
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): at android.os.BinderProxy.sendDeathNotice(Binder.java:470)
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): at com.android.server.SystemServer.init1(Native Method)
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): at com.android.server.SystemServer.main(SystemServer.java:1066)
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): at java.lang.reflect.Method.invokeNative(Native Method)
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): at java.lang.reflect.Method.invoke(Method.java:525)
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): at dalvik.system.NativeStart.main(Native Method)
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): WIN DEATH: null
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): Late-enabling CheckJNI
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): Start proc com.example.solaceap for activity com.example.solaceap/.MainPage: pid=2310 uid=10050 gids={50050, 3003, 1015, 1028}
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): GC_FOR_ALLOC freed 39K, 4% free 2502K/2604K, paused 2ms, total 2ms
??-?? ??:??:??.???: INFO/<unknown>(<unknown>): Grow heap (frag case) to 5.000MB for 2621452-byte allocation
这就是我得到图像的方式:
ImageLoader loader = ImageLoader.getInstance();
public static Map<Integer, Bitmap> movies_bitmaps = new HashMap<Integer, Bitmap>();
loader.loadImage(url, new SimpleImageLoadingListener() {
@Override
public void onLoadingComplete(String imageUri, View view,
Bitmap loadedImage) {
try {
int size = loadedImage.getWidth()
* loadedImage.getHeight();
ByteArrayOutputStream stream = new ByteArrayOutputStream(
size);
Bitmap modified_image = Bitmap.createScaledBitmap(loadedImage, 180, 230, false);
modified_image.compress(Bitmap.CompressFormat.JPEG, 100,
stream);
movies_bitmaps.put(index, modified_image);
loadedImage.recycle();
stream.close();
modified_image = null;
stream = null;
} catch (Exception e) {
e.printStackTrace();
}
答案 0 :(得分:1)
你的代码什么都不做......首先你创建一个大小等于图像宽度*高度的ByteArrayOutputStream
,无论你如何看待它都是错误的:如果你正在编写原始位图数据它应该是4 *宽*高,但是你正在编写一个压缩的JPG,其结果大小与图像宽度/高度无关。然后关闭并将流设置为null,这样就无法完成任何操作。然后你调用loadedImage.recycle()
,所以不能再次使用loadedImage,但你把它放在一个明确意图稍后使用它的Map中......
尝试删除loadedImage.recycle()并查看它是否有帮助,并阅读Bitmap.recycle()上的Android文档:
在评论中回答您的其他一些问题:
所以,如果清除Bitmap,为什么那些图像呢?
根据Android文档:
这不会同步释放像素数据;它只是允许它 如果没有其他参考资料,则进行垃圾收集。
基本上,这意味着如果您调用recycle()
,则就API而言,后续行为是未定义的。如果内存服务,Andorid 4.0和post(包括)Android 4.0之前的行为是不同的,因为他们已经将位图从本机内存空间移动到VM托管内存空间的byte []缓冲区。
GC_FOR_ALLOC消息仍在那里。
因为您仍在创建大量大型对象,所以这是正常的。如果要减少它,请删除ByteArrayOutputStream
及相关代码。