the - Android-view.Surface OutOfResourcesException
leakcanary (7)
Parece que mi aplicación Android no está publicando sus vistas cuando me desplazo dentro de ella con la navegación ListView y con la tecla de menú estándar. Después de un centenar de cargas diferentes (de las 10 o más vistas únicas), comienza el retraso y el cribado negro.
Registro de errores:
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
revela lo siguiente:
#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}}
Por lo tanto, si entiendo correctamente, algo así como 112 vistas se mantienen en la memoria. ¿Hay algo que pueda hacer al respecto? ¿Hay un cheque o una bandera o un parámetro que me falta? ¿Estoy malinterpretando el vertedero?
¡Gracias!
(Aunque esto fue hace un año, vine aquí a través de Google)
Algo me dice que tienes demasiadas vistas cargadas a la vez y Android no puede hacer un seguimiento de todas ellas. * Esto sonó como que no se usa correctamente el ListView, que es algo de lo que muchos de nosotros somos culpables. Suponiendo que tiene un adaptador de matriz personalizado:
public abstract View getView (int position, View convertView, ViewGroup parent)
Cuando sobrecargue esta función, siempre verifique 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 tiene un mecanismo de "papelera de reciclaje" para vistas de vista de lista, y reutilizará las vistas si es posible. En otras palabras, en lugar de crear un conjunto de vistas diferentes, obtendrá una vista anterior de la papelera de reciclaje.
En tu caso, tienes 10 tipos diferentes de vistas. Si son muy similares, puede hacer una supervista y activar o desactivar partes de la vista (por ejemplo, subView.setVisibility (View.GONE)). Solo ten cuidado con bloques de declaración masiva. No los he usado antes, pero debes investigar
public abstract int getItemViewType (int position)
public abstract int getViewTypeCount ()
Esto sería mejor porque no tienes que lidiar con pelusas extra, y debe ser administrado automáticamente por Android
- Personalmente, no estoy 100% seguro de que esto podría ser, pero tengo la sensación de que hay un 66% de posibilidades de que sea esto
En mi caso, apareció el error porque estaba usando la clase Window para cambiar el color de mi barra de estado que solo se admite en las versiones de compilación de Android que son más nuevas que las 21. agrega lo siguiente a tu código y podría funcionar
if(Build.VERSION.SDK_INT >= 21) {
//... your code with Window class here
}
Este es un problema de Surface Flinger, que mantendrá y compondrá Surfaces of Application en el dispositivo de visualización.
intente esto: reduzca su formato de píxeles de diseño en el archivo xml.
Intente extender sus actividades para que pueda ver si se están recogiendo basura (se llama a finalize ()). Del mismo modo, intente ampliar sus Vistas para ayudar a identificar si se están recogiendo basura.
Si está colocando Vistas y Actividades en Colecciones para el almacenamiento en caché, trate de usar objetos de colección que usen WeakReference, como WeakHashMap. ¿Estás usando clases internas en tus Vistas o Actividades? Si es así, estas clases contienen una referencia a la Actividad o Vista y evitan que sean basura recolectada. Un buen ejemplo es una AsyncTask que es una clase interna. Esta tarea se ejecuta en su propio hilo, y puede continuar aferrándose a Vistas incluso cuando haya cerrado la actividad,
Además, mire las variables estáticas, ¿se aferran a los objetos?
Si puedo dejar una nota aquí:
Tenía estos mismos registros mientras estaba probando en mi Prestigo PMP5080B. Mi aplicación también bloqueó al azar.
Me he dado cuenta de que cuando desconecto el cable USB (basta con desconectar la conexión de la tableta haciendo clic en la configuración) la aplicación funciona bien. También me di cuenta de que, mientras estoy conectado a mi aplicación con Eclipse y a través de USB, la tarjeta SD no puede montarse, pero no sé si este problema está conectado de algún modo a mi aplicación, ya que no almacena en SD.
hth
Tuve el mismo problema y finalmente lo resolví. La solución:
Inicie su aplicación desde Eclipse y juegue un poco con ella mientras observa constantemente LogCat-Console en Eclipse. Cuando comiences una nueva actividad o algo así deberías ver:
Tag:"WindowManagerImpl", Text:"addView, new view, mViews[1]:....".
Lo importante aquí es mViews[x]-part
. x te dice cuántas vistas están activas. Ahora cuando comienza una actividad, pero el contador mViews le dice que tiene 5-10 nuevas vistas, entonces puede estar seguro de que accidentalmente cree demasiadas vistas. De esa forma puedes encontrar el punto débil en tu código.
Esto sucedió en mi aplicación de juego: cada vez que perdía el juego, se iniciaban 5 o más GameOverActivities nuevas, porque el código, que comenzaba una nueva GameOverActivity estaba en un bucle. Entonces, después de unos minutos de jugar, había 20 GameOverViews inutilizadas que consumían mis recursos. (Por lo tanto, tenga cuidado al iniciar actividades en bucles).
Una buena forma de comprobar para ver de dónde provienen las fugas es, si se encuentra en Eclipse, Ventana-> Abrir Perspecivo-> DDMS, luego seleccione el proceso en ejecución desde la selección del proceso y use el rastreador de asignación. Inicie la aplicación pero NO toque la aplicación antes de iniciar el rastreador de asignación. Luego haga lo que crea que causará el problema y luego verifique las asignaciones todo el tiempo. Esto debería mostrarle exactamente qué código está causando una fuga.
Además, si publica su código, podemos echarle un vistazo.