Memory growth at surfaceflinger process on Android x86 platforms

790 views Asked by At

I am using Virtual displays to take screenshots from Android emulators and I noticed that surfaceflinger's memory has infinite growth (this can be seen in top program) and the emulator stops working after some time. On real Android devices everything works fine: the memory increases by 5Mb and then it is cleared. But on emulators such as GenyMotion and LDPlayer surfaceflinger works abnormally. I tried two different approaches of creating VirtualDisplay: through 1)ImageReader or 2)GLES:

  1. ImageReader
        val handlerThread = HandlerThread(
            javaClass.simpleName,
            Process.THREAD_PRIORITY_BACKGROUND
        ).apply { start() }
        val handler = Handler(handlerThread.looper)

        latestBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 2)

        imageReader?.setOnImageAvailableListener(this, handler)
        val projection = mediaProjectionManager.getMediaProjection(resultCode, resultData)


        projection!!.createVirtualDisplay(
                "shooter",
                width,
                height,
                context.resources.displayMetrics.densityDpi,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                imageReader?.surface,
                null,
                null
        )
  1. GLES
        val eglCore = EglCore(null, EglCore.FLAG_TRY_GLES3)
        val consumerSurface = eglCore.createOffscreenSurface(width, height)
        eglCore.makeCurrent(consumerSurface)

        val shader = Texture2dProgram(Texture2dProgram.ProgramType.TEXTURE_EXT)
        val screen = FullFrameRect(shader);

        val textureId = screen.createTextureObject()
        val texture = SurfaceTexture(textureId, false)
        texture.setDefaultBufferSize(width, height)
        val producerSide = Surface(texture)

        val matrix = FloatArray(16)

        var closed: Boolean = false
        val buf = ByteBuffer.allocateDirect(width * height * 4)
        buf.order(ByteOrder.nativeOrder())
        val currentBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)

        texture.setOnFrameAvailableListener(object : SurfaceTexture.OnFrameAvailableListener {
            override fun onFrameAvailable(surfaceTexture: SurfaceTexture?) {
                Log.d("FRAME", "frame")

                // there may still be pending callbacks after shutting down EGL
                if (closed) return;

                eglCore.makeCurrent(consumerSurface)

                texture.updateTexImage()
                texture.getTransformMatrix(matrix)

                eglCore.makeCurrent(consumerSurface)

                // draw the image to framebuffer object
                screen.drawFrame(textureId, matrix)
                eglCore.swapBuffers(consumerSurface)

                buf.rewind()
                GLES20.glReadPixels(0, 0, width, height, GLES10.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buf)

                buf.rewind()
                currentBitmap.copyPixelsFromBuffer(buf)

            }
        })
        val mediaProjectionManager = context.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
        val projection = mediaProjectionManager.getMediaProjection(resultCode, resultData)
        projection!!.createVirtualDisplay(
            "shooter",
            width,
            height,
            context.resources.displayMetrics.densityDpi,
            DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
            producerSide,
            null,
            null
        )

There are grafica classes at the 2-nd solution.

In LDPlayer's logcat I can see such messages after screenshooter start in both cases: EGL adreno: eglMakeCurrent: 0xc77d6480: ver 3 1 (tinfo 0xc77cb700)

And there is such Low Memory log after about an hour app work with 1Gb of RAM:

05-04 12:55:00.464  1181  1181 D EGL_adreno: eglMakeCurrent: 0xc77d6480: ver 3 1 (tinfo 0xc77cb720)
05-04 12:55:00.494  1303  1652 D GraphicsStats: Buffer count: 2
05-04 12:55:00.495  1181  1181 D EGL_adreno: eglMakeCurrent: 0xc77d6480: ver 3 1 (tinfo 0xc77cb720)
05-04 12:55:00.495  1303  1781 I VirtualDisplayAdapter: Virtual display device released because application token died: com.myapp
05-04 12:55:00.495  1303  1652 I ActivityManager: Process com.myapp (pid 1998) has died
05-04 12:55:00.495  1303  1652 D ActivityManager: cleanUpApplicationRecord -- 1998
05-04 12:55:00.495  1181  1181 E Surface : queueBuffer: error queuing buffer to SurfaceTexture, -32
05-04 12:55:00.495  1181  1181 E EGL_adreno: tid 1181: swapBuffers(577): error 0x300d (EGL_BAD_SURFACE)
05-04 12:55:00.495  1181  1181 E DisplayDevice: eglSwapBuffers(0x1, 0xc60ff720) failed with 0x0000300d
05-04 12:55:00.496  1181  1181 D EGL_adreno: eglMakeCurrent: 0xc77d6480: ver 3 1 (tinfo 0xc77cb720)
05-04 12:55:00.496  1303  1652 W ActivityManager: Scheduling restart of crashed service com.myapp/.presentation.service.HelpService in 1000ms
05-04 12:55:00.497  1303  1652 I ActivityManager: Process com.myapp (pid 0), (curAdj 200) has died.
05-04 12:55:00.497  1303  1652 I ActivityManager: Tell the tab as app process died as low mem.
05-04 12:55:00.498  1746  1746 W ContextImpl: Calling a method in the system process without a qualified user: android.app.ContextImpl.startService:1357 android.content.ContextWrapper.startService:613 android.content.ContextWrapper.startService:613 com.android.coreservice.CoreBroadcastReceiver.onReceive:60 android.app.ActivityThread.handleReceiver:3045
05-04 12:55:00.520  1303  1346 I DisplayManagerService: Display device removed: DisplayDeviceInfo{"shooter": uniqueId="virtual:com.myapp,10054,shooter,0", 707 x 1259, modeId 2, defaultModeId 2, supportedModes [{id=2, width=707, height=1259, fps=60.0}], colorMode 0, supportedColorModes [0], HdrCapabilities null, density 480, 480.0 x 480.0 dpi, appVsyncOff 0, presDeadline 16666666, touch NONE, rotation 0, type VIRTUAL, state ON, owner com.myapp (uid 10054), FLAG_PRESENTATION}
05-04 12:55:00.578  1181  1181 W libEGL  : EGLNativeWindowType 0xc5865808 disconnect failed
05-04 12:55:00.616  1303  2098 I ActivityManager: Low on memory:
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N   162240: surfaceflinger (pid 1181) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N    16987: mediaserver (pid 1194) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N    14907: media.codec (pid 1190) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N    10022: zygote (pid 1184) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N     7448: media.extractor (pid 1193) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N     2259: audioserver (pid 1185) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N     1920: logd (pid 1123) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N     1509: mediadrmserver (pid 1192) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N     1441: cameraserver (pid 1186) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N     1284: sdcard (pid 1459) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N     1227: adbd (pid 1182) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N     1141: drmserver (pid 1187) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N      994: vold (pid 1132) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N      930: netd (pid 1195) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N      909: /init (pid 1) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N      872: healthd (pid 1178) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N      706: keystore (pid 1189) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N      655: gatekeeperd (pid 1197) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N      566: lmkd (pid 1179) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N      529: ueventd (pid 891) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N      526: rild (pid 1196) native
05-04 12:55:00.616  1303  2098 I ActivityManager:   ntv   N     3506: (Other native)
05-04 12:55:00.616  1303  2098 I ActivityManager:   sys   P    48568: system (pid 1303) fixed
05-04 12:55:00.616  1303  2098 I ActivityManager:   pers  P    30288: com.android.systemui (pid 1476) fixed
05-04 12:55:00.616  1303  2098 I ActivityManager:   pers  P    16338: com.android.phone (pid 1615) fixed
05-04 12:55:00.616  1303  2098 I ActivityManager:   pers  P    10282: com.android.coreservice (pid 1746) fixed
05-04 12:55:00.616  1303  2098 I ActivityManager:   fore  T    34427: com.android.gallery3d (pid 2030) top-activity
05-04 12:55:00.616  1303  2098 I ActivityManager:   vis   SB    8551: android.ext.services (pid 1727) service
05-04 12:55:00.616  1303  2098 I ActivityManager:                        android.ext.services/.notification.Ranker<=Proc{1303:system/1000}
05-04 12:55:00.616  1303  2098 I ActivityManager:   prcp  IB   10481: com.android.inputmethod.pinyin (pid 1889) service
05-04 12:55:00.616  1303  2098 I ActivityManager:                        com.android.inputmethod.pinyin/.InputService<=Proc{1303:system/1000}
05-04 12:55:00.616  1303  2098 I ActivityManager:             391513: TOTAL
05-04 12:55:00.616  1303  2098 I ActivityManager:   MemInfo:    15,096K slab,    14,348K shmem,    12,876K vm alloc,     3,664K page tables     2,712K kernel stack
05-04 12:55:00.616  1303  2098 I ActivityManager:                  952K buffers,   126,980K cached,   111,108K mapped,    72,676K free
05-04 12:55:00.616  1303  2098 I ActivityManager:   Free RAM:    89,500K
05-04 12:55:00.616  1303  2098 I ActivityManager:   Used RAM:   440,209K
05-04 12:55:00.616  1303  2098 I ActivityManager:   Lost RAM:   -22,345K
05-04 12:55:35.664  1303  1426 D WifiNative-HAL: Failing getSupportedFeatureset because HAL isn't started
05-04 12:55:35.666  1303  1327 E BatteryStatsService: no controller energy info supplied
05-04 12:55:35.666  1303  1327 E BatteryStatsService: no controller energy info supplied
05-04 12:55:35.680  1615  1615 E PhoneInterfaceManager: [PhoneIntfMgr] queryModemActivityInfo: Empty response
05-04 12:55:35.691  1303  1327 E KernelCpuSpeedReader: Failed to read cpu-freq: /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state (No such file or directory)
05-04 12:55:35.691  1303  1327 E BatteryStatsService: modem info is invalid: ModemActivityInfo{ mTimestamp=0 mSleepTimeMs=0 mIdleTimeMs=0 mTxTimeMs[]=[0, 0, 0, 0, 0] mRxTimeMs=0 mEnergyUsed=0}
05-04 12:56:00.006  1303  1322 I ProcessStatsService: Prepared write state in 6ms
05-04 12:56:00.008  1303  1320 I ProcessStatsService: Pruning old procstats: /data/system/procstats/state-2021-05-03-10-19-58.bin
05-04 12:56:20.628  1303  1426 D WifiStateMachine: setScanResults mScanResults.size=1
05-04 12:59:00.628  1303  1426 D WifiStateMachine: setScanResults mScanResults.size=1

I can take screenshots through file saving but it works awful. Could you please tell how can I make screenshots without memory consumption? My previous question was asked here - I did not know the cause of the problem. Also I asked the question in official Google Android community but I got no answer.

P.S. I found out that Android 10 in Genymotion works fine but I can't upgrade any user friendly emulator up to this version

1

There are 1 answers

1
bilabila On

I encounter same issue on genymotion android 7, surfaceflinger process can eat up to 70% memory. I have to restart machine to release memory.

Finally I switch to genymotion android 10, and this problem never occur.