Android - view.Surface OutOfResourcesException
当我使用 ListView 导航和标准菜单键在其中移动时,我的 Android 应用程序似乎没有释放其视图。在加载一百个左右不同的(大约 10 个独特视图中的)后,它开始出现滞后和黑屏。
错误日志:
07-01 09:54:42.913: INFO/ActivityManager(1279): Starting: Intent { cmp=com.site.android.conferencecompanion/.Search } from pid 31290
07-01 09:54:43.013: ERROR/msm7x30.gralloc(1279): /dev/pmem: no more pmem available
07-01 09:54:43.013: ERROR/msm7x30.gralloc(1279): couldn't open pmem (No such file or directory)
07-01 09:54:43.013: ERROR/msm7x30.gralloc(1279): gralloc failed err=Out of memory
07-01 09:54:43.013: WARN/GraphicBufferAllocator(1279): alloc(480, 800, 1, 00000133, ...) failed -12 (Out of memory)
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): Allocated buffers:
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x290740: 1500.00 KiB | 480 ( 480) x 800 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x307448: 60.00 KiB | 102 ( 128) x 120 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x32e4c0: 71.25 KiB | 480 ( 480) x 38 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x3caad8: 60.00 KiB | 102 ( 128) x 120 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x4a47f8: 1346.25 KiB | 480 ( 480) x 718 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x4f9710: 1500.00 KiB | 480 ( 480) x 800 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x54c500: 1500.00 KiB | 480 ( 480) x 800 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x5d1c00: 1500.00 KiB | 480 ( 480) x 800 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x5f5f98: 1500.00 KiB | 480 ( 480) x 800 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x604600: 60.00 KiB | 126 ( 128) x 120 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x60a3d0: 750.00 KiB | 480 ( 480) x 800 | 4 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x661270: 1428.75 KiB | 480 ( 480) x 762 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x6830b8: 750.00 KiB | 480 ( 480) x 800 | 4 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x70e0e8: 1500.00 KiB | 480 ( 480) x 800 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x71f238: 71.25 KiB | 480 ( 480)
07-01 09:54:43.013: ERROR/SurfaceFlinger(1279): Layer::requestBuffer(this=0x189d50), index=0, w=480, h=800 failed (Out of memory)
07-01 09:54:43.013: ERROR/Surface(31290): Surface (identity=4545) requestBuffer(0, 0, 0, 0, 00000033) returned a buffer with a null handle
07-01 09:54:43.013: ERROR/Surface(31290): getBufferLocked(0, 0, 0, 0, 00000033) failed (Out of memory)
07-01 09:54:43.013: ERROR/Surface(31290): dequeueBuffer failed (Out of memory)
07-01 09:54:43.013: ERROR/ViewRoot(31290): OutOfResourcesException locking surface
07-01 09:54:43.013: ERROR/ViewRoot(31290): android.view.Surface$OutOfResourcesException
07-01 09:54:43.013: ERROR/ViewRoot(31290): at android.view.Surface.lockCanvasNative(Native Method)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at android.view.Surface.lockCanvas(Surface.java:314)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at android.view.ViewRoot.draw(ViewRoot.java:1457)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at android.view.ViewRoot.performTraversals(ViewRoot.java:1259)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at android.view.ViewRoot.handleMessage(ViewRoot.java:1860)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at android.os.Handler.dispatchMessage(Handler.java:99)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at android.os.Looper.loop(Looper.java:123)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at android.app.ActivityThread.main(ActivityThread.java:3839)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at java.lang.reflect.Method.invokeNative(Native Method)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at java.lang.reflect.Method.invoke(Method.java:507)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at dalvik.system.NativeStart.main(Native Method)
07-01 09:54:43.203: INFO/ActivityManager(1279): Displayed com.site.android.conferencecompanion/.Search: +292ms
adb shell dumpsys window
显示以下内容:
#1 - #29, junk
#30: AppWindowToken{40bbc000 token=HistoryRecord{408cc260 com.site.android.conferencecompanion/.ProgramDates}}
...
#142: AppWindowToken{40ba65a8 token=HistoryRecord{40b93808 com.site.android.conferencecompanion/.ProgramSpeakers}}
因此,如果我理解正确的话,内存中将保存 112 个视图之类的内容。我能做点什么吗?我是否缺少检查、标志或参数?我是否误解了转储?
谢谢!
My Android app seems to not be releasing its views when I move around inside of it with ListView navigation and with the standard Menu key. After a hundred or so different (of the 10 or so unique views) loads, it starts lagging and black screening.
Error log:
07-01 09:54:42.913: INFO/ActivityManager(1279): Starting: Intent { cmp=com.site.android.conferencecompanion/.Search } from pid 31290
07-01 09:54:43.013: ERROR/msm7x30.gralloc(1279): /dev/pmem: no more pmem available
07-01 09:54:43.013: ERROR/msm7x30.gralloc(1279): couldn't open pmem (No such file or directory)
07-01 09:54:43.013: ERROR/msm7x30.gralloc(1279): gralloc failed err=Out of memory
07-01 09:54:43.013: WARN/GraphicBufferAllocator(1279): alloc(480, 800, 1, 00000133, ...) failed -12 (Out of memory)
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): Allocated buffers:
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x290740: 1500.00 KiB | 480 ( 480) x 800 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x307448: 60.00 KiB | 102 ( 128) x 120 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x32e4c0: 71.25 KiB | 480 ( 480) x 38 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x3caad8: 60.00 KiB | 102 ( 128) x 120 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x4a47f8: 1346.25 KiB | 480 ( 480) x 718 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x4f9710: 1500.00 KiB | 480 ( 480) x 800 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x54c500: 1500.00 KiB | 480 ( 480) x 800 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x5d1c00: 1500.00 KiB | 480 ( 480) x 800 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x5f5f98: 1500.00 KiB | 480 ( 480) x 800 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x604600: 60.00 KiB | 126 ( 128) x 120 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x60a3d0: 750.00 KiB | 480 ( 480) x 800 | 4 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x661270: 1428.75 KiB | 480 ( 480) x 762 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x6830b8: 750.00 KiB | 480 ( 480) x 800 | 4 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x70e0e8: 1500.00 KiB | 480 ( 480) x 800 | 1 | 0x00000133
07-01 09:54:43.013: DEBUG/GraphicBufferAllocator(1279): 0x71f238: 71.25 KiB | 480 ( 480)
07-01 09:54:43.013: ERROR/SurfaceFlinger(1279): Layer::requestBuffer(this=0x189d50), index=0, w=480, h=800 failed (Out of memory)
07-01 09:54:43.013: ERROR/Surface(31290): Surface (identity=4545) requestBuffer(0, 0, 0, 0, 00000033) returned a buffer with a null handle
07-01 09:54:43.013: ERROR/Surface(31290): getBufferLocked(0, 0, 0, 0, 00000033) failed (Out of memory)
07-01 09:54:43.013: ERROR/Surface(31290): dequeueBuffer failed (Out of memory)
07-01 09:54:43.013: ERROR/ViewRoot(31290): OutOfResourcesException locking surface
07-01 09:54:43.013: ERROR/ViewRoot(31290): android.view.Surface$OutOfResourcesException
07-01 09:54:43.013: ERROR/ViewRoot(31290): at android.view.Surface.lockCanvasNative(Native Method)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at android.view.Surface.lockCanvas(Surface.java:314)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at android.view.ViewRoot.draw(ViewRoot.java:1457)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at android.view.ViewRoot.performTraversals(ViewRoot.java:1259)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at android.view.ViewRoot.handleMessage(ViewRoot.java:1860)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at android.os.Handler.dispatchMessage(Handler.java:99)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at android.os.Looper.loop(Looper.java:123)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at android.app.ActivityThread.main(ActivityThread.java:3839)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at java.lang.reflect.Method.invokeNative(Native Method)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at java.lang.reflect.Method.invoke(Method.java:507)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
07-01 09:54:43.013: ERROR/ViewRoot(31290): at dalvik.system.NativeStart.main(Native Method)
07-01 09:54:43.203: INFO/ActivityManager(1279): Displayed com.site.android.conferencecompanion/.Search: +292ms
adb shell dumpsys window
reveals the following:
#1 - #29, junk
#30: AppWindowToken{40bbc000 token=HistoryRecord{408cc260 com.site.android.conferencecompanion/.ProgramDates}}
...
#142: AppWindowToken{40ba65a8 token=HistoryRecord{40b93808 com.site.android.conferencecompanion/.ProgramSpeakers}}
So, if I understand correctly, something like 112 views are being held in memory. Is there something I can do about this? Is there a check or a flag or a parameter I'm missing? Am I misinterpretting the dump?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
检查泄漏来自何处的一个好方法是,如果您在 Eclipse 中,则 Window->Open Perspective ->然后,DDMS 从进程选择中选择正在运行的进程并使用分配跟踪器。启动应用程序,但在启动分配跟踪器之前请勿触摸应用程序。然后执行您认为会导致问题的操作,然后每次检查分配情况。这应该可以准确地告诉您哪些代码导致了泄漏。
另外,如果您发布代码,我们可以看一下。
A great way to check to see where leaks are coming from is , if you are in Eclipse, Window->Open Perspecive -> DDMS then select the running process from the process selection and use the allocation tracker.Boot the app but DO NOT touch the app before you start the allocation tracker. Then do what you think will cause the problem and then check the allocations every time. This should show you exactly what code is causing a leak.
Also if you post you code we could take a look at it.
(尽管这是一年前的事,我是通过 Google 来到这里的)
有件事告诉我,您一次加载的视图太多,而 Android 无法跟踪所有视图。 * 这听起来像是没有正确使用 ListView,这是我们很多人都犯过的错误。假设您有一个自定义数组适配器:
当您重载此函数时,请始终检查convertView。
Android 对于列表视图视图有一个“回收站”机制,并且如果可能的话将重用视图。换句话说,它不会创建一堆不同的视图,而是从回收站中获取旧视图。
就您而言,您有 10 种不同的观点。如果它们非常相似,您可以创建一个超级视图并打开或关闭部分视图(例如 subView.setVisibility(View.GONE))。只需要注意大量的 if 语句块。我以前没有使用过这些,但你应该调查一下
这会更好,因为你不必处理额外的绒毛,而且它应该由Android自动管理就
(Even though this was a year ago, I came here via Google)
Something tells me that you have too many views loaded at once and Android can't keep track of them all. * This sounded like not using the ListView correctly, which is something a lot of us are guilty of. Assuming that you have a custom array adapter:
When you overload this function, always check convertView.
Android has a "recycle bin" mechanism for listview views, and will reuse views if all possible. In other words, instead of creating a bunch of different views, it'll grab an old view from the recycle bin.
In your case, you have 10 different kind of views. If they are very similar, you can make a superview and turn on or turn off parts of the view (example being subView.setVisibility(View.GONE)). Just watch out for massive if statement blocks. I haven't used these before, but you should investigate
This would be better because you don't have to deal with extra fluff, and it should be automatically managed by Android
尝试扩展您的活动,以便您可以查看它们是否正在被垃圾收集(调用finalize())。同样,尝试扩展您的视图以帮助确定它们是否正在被垃圾收集。
如果要将视图和活动放入集合中进行缓存,请尝试使用使用 WeakReference 的集合对象,例如 WeakHashMap。您是否在视图或活动中使用内部类?如果是这样,这些类将保留对 Activity 或 View 的引用并防止它们被垃圾收集。一个很好的例子是作为内部类的 AsyncTask。该任务在自己的线程中运行,即使您关闭了活动,也可以继续保留视图,
另外,查看静态变量,它们是否保留对象?
Try extending your Activities so you can see if they are being garbage collected (finalize() being called). Similarly, try extending your Views to help identify if they are being garbage collected.
If you are putting Views and Activities into Collections for caching, trying using collection objects that use WeakReference, such as WeakHashMap. Are you using inner classes in your Views or Activities? If so, these classes holds a reference to the Activity or View and prevent them from being garbage collected. A good example is an AsyncTask that is an inner class. This task runs in its own thread, and can continue to hold on to Views even when you have closed the activity,
Also, look at static variables, are they holding on to objects?
这是SurfaceFlinger的问题,SurfaceFlinger将维护应用程序的Surface并将其组合成显示设备。
试试这个:减少 xml 文件中的布局像素格式。
This is problem from Surface Flinger, Which will maintain and compose Surfaces of Application into display device.
try this : reduce your layout pixel format in xml file .
我可以在这里留言:
当我在 Prestigo PMP5080B 上进行测试时,我也有同样的日志。
我的应用程序也会随机阻止。
我注意到,当我断开 USB 电缆时(通过单击设置来关闭平板电脑的连接就足够了),应用程序运行正常。
我还注意到,当我使用 Eclipse 并通过 USB 连接到我的应用程序时,无法安装 SD 卡,但不知道这个问题是否以某种方式连接到我的应用程序,因为我没有存储在 SD 上。
哈
If I may leave a note here:
I had this same logs while I was testing on my Prestigo PMP5080B.
My app would also random block.
I have noticed that when I disconnect the USB cable (it is enough to swtich off the connection from the tablet by clicking in settings) the app works OK.
I have also noticed that while I am connected to my app using Eclipse and through USB that the SD card can not be mounted but do not know if this problem is connected somehow to my app since I do not store on SD.
hth
我也遇到了同样的问题,终于解决了。
解决方案:
从 Eclipse 启动您的应用程序并使用它,同时不断观察 Eclipse 中的 LogCat-Console。当启动一个新的 Activity 或类似的内容时,您应该看到:
这里重要的是
mViews[x]-part
。 x 告诉您有多少视图处于活动状态。现在,当您启动一个 Activity 但 mViews-Counter 告诉您它有 5-10 个新视图时,您可以确定您不小心创建了太多视图。
这样你就可以找到代码中的弱点。
这发生在我的游戏应用程序中:每次我输掉游戏,都会启动 5 个或更多新的 GameOverActivity,因为启动新 GameOverActivity 的代码处于循环中。因此,玩了几分钟后,有 20 个未使用的 GameOverView 耗尽了我的资源。
(因此在循环中启动活动时要小心。)
I had the same problem and finally solved it.
The solution:
Start your app from Eclipse and play a little with it while constantly observing the LogCat-Console in Eclipse. When starting a new Activity or something like that you should see:
The important thing here is the
mViews[x]-part
. x tells you how many views are active.Now when you start an activity but the mViews-Counter tells you that it has 5-10 new views, then you can be sure that you accidentally create too many views.
That way you can find the weak point in your code.
This happened in my game app: everytime I lost the game 5 or more new GameOverActivities were started, because the code, which started a new GameOverActivity was in a loop. So after a few minutes of playing there were 20 unused GameOverViews eating up my resources.
(So be careful when starting activities in loops.)
就我而言,出现错误是因为我正在使用 Window 类来更改状态栏颜色,该颜色仅在高于 21 的 Android 构建版本中受支持。将以下内容添加到您的代码中,它可能会起作用
In my case, the error showed up because i was using Window class to change my status bar color which is supported only in android build versions that are newer than 21. add the following to your code and it might work