Android - view.Surface OutOfResourcesException
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): deque开发者_开发知识库ueBuffer 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!
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.
(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:
public abstract View getView (int position, View convertView, ViewGroup parent)
When you overload this function, always check convertView.
public abstract View getView (int position, View convertView, ViewGroup parent)
{
View view = convertView;
if ( view == null )
{
// create/inflate the view here
// ex: view = inflater.inflate(R.layout.bob, null);
// configure the static parts here
}
// configure the dynamic parts here
return view;
}
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
public abstract int getItemViewType (int position)
public abstract int getViewTypeCount ()
This would be better because you don't have to deal with extra fluff, and it should be automatically managed by Android
- Personally, I'm not 100% sure that this could be it, but I have the feeling that there's a 66% chance it's this
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?
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 .
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
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:
Tag:"WindowManagerImpl", Text:"addView, new view, mViews[1]:....".
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.)
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
if(Build.VERSION.SDK_INT >= 21) {
//... your code with Window class here
}
精彩评论