一次OOM纪实

在最近的一次项目开发中 

我遇到了 

Adreno-GSL: : GSL MEM ERROR: kgsl_sharedmem_alloc ioctl failed.

最终:

OpenGLRenderer: GL error:  Out of memory!
OpenGLRenderer: glViewport error! GL_OUT_OF_MEMORY (0x505)

实现了这些 ...

其主要原因是项目中需要使用到Webview来开发。Webview的确是一个很强大的东西,使用它开发后,我客户端的代码量少了很多很多。不过WebView的使用也是存在很多问题的。其中问题比较大的就是硬件加速的问题吧。在Android 3.0版本以上,都使用了硬件加速,不可否认,使用硬件加速的确带来了很多好处,就如,浏览的流畅度很不错。但是它也带来了一些问题。

在Android 4.0的某些设备上,在View刷新时会出现花屏和屏幕上的某些View错位的现象。 经过调查后发现adb logcat中出现很多OpenGLRenderer: 0x501的错位:

10-06 11:34:39.090: DEBUG/OpenGLRenderer(3104): GL error from OpenGLRenderer: 0x501
10-06 11:34:39.386: DEBUG/OpenGLRenderer(3104): GL error from OpenGLRenderer: 0x501
10-06 11:34:39.656: DEBUG/OpenGLRenderer(3104): GL error from OpenGLRenderer: 0x501

从这个日志,初步怀疑是硬件加速导致的问题。 经过分析发现使用了比较复杂的自定义View,可能会导致硬件加速渲染出错.

硬件加速的优点与缺点

硬件加速能使用GPU来加速2D图像的渲染速度,但是硬件加速并不能完全支持所有的渲染操作, 针对自定义的View,硬件加速可能导致渲染出现错误。 如果有自定义的View,需要在硬件加速的设备上进行测试,如果出现渲染的问题,需要关闭硬件加速。

开启和关闭硬件加速

对硬件加速的开关可以在不同的级别进行控制:

  • Application
  • Activity
  • Windows
  • View

Application级别

在Applciation级别控制硬件加速的开关:

Activity级别

可以对单个的Activity控制是否启用硬件加速:





Window级别

getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

View级别

在指定的View上关闭硬件加速:

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

或者使用android:layerType="software"来关闭硬件加速:


如何判断一个View是否启用了硬件加速

  • View.isHardwareAccelerated()     returns true if the View is attached to a hardware accelerated window.
  • Canvas.isHardwareAccelerated()    returns true if the Canvas is hardware accelerated

而小翊的问题就是在主页面的Recycler因为是自定义的View,无意间开启了硬件加速,当然还有一些其他原因的内存泄漏点...

而我的Recycler中的item又都是以高清图片为主,因为我在全局开启了硬件加速导致的疯狂绘制,最后就在疯狂(绘制View)的时候导致OOM... 

可参考官方文档:http://developer.android.com/guide/topics/graphics/hardware-accel.html

硬件加速技术分析:https://blog.csdn.net/coloriy/article/details/74395236

 

 

你可能感兴趣的:(Android)