Skip to content

[FlutterGPU] Acquiring and Submitting Command Buffers leads to OOM on Android #172068

@LordNed

Description

@LordNed

Steps to reproduce

Upgrade to latest and initialize a new repro;

flutter channel master
flutter upgrade
flutter create gpu_oom_repro
cd gpu_oom_repro
flutter pub add flutter_gpu --sdk=flutter

Update android/app/src/main/AndroidManifest.xml with EnableFlutterGPU set to true.

    <application
        android:label="my_cool_renderer"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher">
        <meta-data
            android:name="io.flutter.embedding.android.EnableFlutterGPU"
            android:value="true" 
        />
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:taskAffinity=""
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- Specifies an Android theme to apply to this Activity as soon as
                 the Android process has started. This theme is visible to the user
                 while the Flutter UI initializes. After that, this theme continues
                 to determine the Window background behind the Flutter UI. -->
            <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme"
              />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
    <!-- Required to query activities that can process text, see:
         https://developer.android.com/training/package-visibility and
         https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.

         In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
    <queries>
        <intent>
            <action android:name="android.intent.action.PROCESS_TEXT"/>
            <data android:mimeType="text/plain"/>
        </intent>
    </queries>
</manifest>

Replace main.dart with:

import 'package:flutter/material.dart';
import 'package:flutter_gpu/gpu.dart' as gpu;

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  MyAppState createState() => MyAppState();
}

class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  @override
  void initState() {
    createTicker((elapsed) {
      setState(() {});
    }).start();

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My 3D app',
      home: CustomPaint(painter: TrianglePainter()),
    );
  }
}

class TrianglePainter extends CustomPainter {

  @override
  void paint(Canvas canvas, Size size) {

    final commandBuffer = gpu.gpuContext.createCommandBuffer();
    commandBuffer.submit();
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

Launch the application on device

flutter run -v

Open a new Terminal Window and use adb to pull memory usage;

adb shell dumpsys meminfo com.example.gpu_oom_repro

Output:

Applications Memory Usage (in Kilobytes):
Uptime: 373960184 Realtime: 3852235493

** MEMINFO in pid 10672 [com.example.gpu_oom_repro] **
                   Pss  Private  Private  SwapPss      Rss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty    Total     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------   ------
  Native Heap    40113    40004       72       45    40840    45520    37609     7910
  Dalvik Heap     2860     2824        4      167     3276     5653     2843     2810
 Dalvik Other     6695     2080        0        3    11488
        Stack     1228     1228        0        0     1232
       Ashmem       40        0        0        0      700
      Gfx dev     7728     7728        0        0     7728
    Other dev      410      356       16        0      776
     .so mmap    13581      232    11272       11    26192
    .jar mmap     9392        0     6712        0    20436
    .apk mmap    11626      564    10672        0    12884
    .ttf mmap     1451        0      240        0     2684
    .dex mmap     6747     6716        0        0     7248
    .oat mmap      117        0       84        0      400
    .art mmap    10657     8300     1364      175    20752
   Other mmap    36890        8    35260        0    38888
   EGL mtrack    38100    38100        0        0    38100
    GL mtrack      576      576        0        0      576
      Unknown    83785    83616      136        1    84116
        TOTAL   272398   192332    65832      402   318316    51173    40452    10720

 App Summary
                       Pss(KB)                        Rss(KB)
                        ------                         ------
           Java Heap:    12488                          24028
         Native Heap:    40004                          40840
                Code:    37064                          79640
               Stack:     1228                           1232
            Graphics:    46404                          46404
       Private Other:   120976
              System:    14234
             Unknown:                                  126172

           TOTAL PSS:   272398            TOTAL RSS:   318316       TOTAL SWAP PSS:      402

 Objects
               Views:        8         ViewRootImpl:        1
         AppContexts:        6           Activities:        1
              Assets:       17        AssetManagers:        0
       Local Binders:       13        Proxy Binders:       42
       Parcel memory:        5         Parcel count:       23
    Death Recipients:        0      OpenSSL Sockets:        0
            WebViews:        0

 SQL
         MEMORY_USED:        0
  PAGECACHE_OVERFLOW:        0          MALLOC_SIZE:        0

After approximately two minutes of idling, TOTAL memory usage has climbed significantly (+200mb). If left idling, eventually the application crashes.

Applications Memory Usage (in Kilobytes):
Uptime: 374108118 Realtime: 3852383427

** MEMINFO in pid 10672 [com.example.gpu_oom_repro] **
                   Pss  Private  Private  SwapPss      Rss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty    Total     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------   ------
  Native Heap   120288   120208       68     4387   120616   128720   124607     4112
  Dalvik Heap     7859     2684     5064       55     8516     5655     2828     2827
 Dalvik Other     6680     1904       48      278    11592
        Stack      868      868        0      288      872
       Ashmem        2        0        0        0        8
      Gfx dev    55960    55960        0        0    55960
    Other dev       37       16        8        0      336
     .so mmap    13432       96    11272      152    26028
    .jar mmap     9424        0     6732        0    20492
    .apk mmap    11383      320    10676      244    12636
    .ttf mmap     1151        0      240        0     2084
    .dex mmap      655      624        0     6092     1156
    .oat mmap      117        0       84        0      400
    .art mmap     7446     3328     3044     5111    17664
   Other mmap    35920        4    34560        4    37648
   EGL mtrack    38100    38100        0        0    38100
    GL mtrack      576      576        0        0      576
      Unknown    97250    97072      148     3741    97568
        TOTAL   427500   321760    71944    20352   452252   134375   127435     6939

 App Summary
                       Pss(KB)                        Rss(KB)
                        ------                         ------
           Java Heap:     9056                          26180
         Native Heap:   120208                         120616
                Code:    30620                          72812
               Stack:      868                            872
            Graphics:    94636                          94636
       Private Other:   138316
              System:    33796
             Unknown:                                  137136

           TOTAL PSS:   427500            TOTAL RSS:   452252       TOTAL SWAP PSS:    20352

 Objects
               Views:        8         ViewRootImpl:        1
         AppContexts:        6           Activities:        1
              Assets:       17        AssetManagers:        0
       Local Binders:       13        Proxy Binders:       42
       Parcel memory:        6         Parcel count:       25
    Death Recipients:        0      OpenSSL Sockets:        0
            WebViews:        0

 SQL
         MEMORY_USED:        0
  PAGECACHE_OVERFLOW:        0          MALLOC_SIZE:        0

Expected results

App should be able to idle without increasing memory usage. This can be achieved by editing the paint(...) function to read as follows:

class TrianglePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    return;
    final commandBuffer = gpu.gpuContext.createCommandBuffer();
    commandBuffer.submit();
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

When skipping createCommandBuffer/submit calls, application memory is stable at approximately ~270mb under the TOTAL row.

Actual results

Crashes with an Out of Memory error after a while.

[+3360 ms] I/e.gpu_oom_repr(10672): Explicit concurrent copying GC freed 815KB AllocSpace bytes, 0(0B) LOS objects, 49% free, 2832KB/5664KB, paused 62us,38us total 22.759ms
[+217708 ms] W/Adreno-GSL(10672): <sharedmem_gpuobj_alloc:2736>: sharedmem_gpumem_alloc: mmap failed errno 12 Out of memory
[   +1 ms] E/Adreno-GSL(10672): <gsl_memory_alloc_pure:2614>: GSL MEM ERROR: kgsl_sharedmem_alloc ioctl failed.
[   +2 ms] F/libc    (10672): Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x1c in tid 10672 (e.gpu_oom_repro), pid 10672 (e.gpu_oom_repro)
[+1728 ms] *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
[        ] Build fingerprint: 'samsung/gta4lwifixx/gta4lwifi:12/SP1A.210812.016/T500XXS8CXG1:user/release-keys'
[        ] Revision: '0'
[        ] ABI: 'arm64'
[        ] Processor: '5'
[        ] Timestamp: 2025-07-12 14:25:52.448201343-0700
[        ] Process uptime: 472s
[        ] Cmdline: com.example.gpu_oom_repro
[        ] pid: 10672, tid: 10672, name: e.gpu_oom_repro  >>> com.example.gpu_oom_repro <<<
[        ] uid: 10017
[        ] signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x1c
[        ] Cause: null pointer dereference
[        ]     x0  b400007d3a6d7940  x1  0000000000000000  x2  0000000000000000  x3  000000000000000f
[        ]     x4  b400007df9bc8000  x5  b400007df9bc80b8  x6  0000000100000000  x7  7f7f7f7f7f7f7f7f
[        ]     x8  d0ac432fc4b89c66  x9  0000000000000000  x10 00000000000001c0  x11 0000007d00000000
[        ]     x12 0000000000000000  x13 000000001c57dfc0  x14 0000000000000001  x15 0000000000000000
[        ]     x16 0000007eaa16ed60  x17 0000007eaa15dcd4  x18 0000007ebbe9c000  x19 b400007d3a6d7940
[        ]     x20 0000000000000001  x21 0000000000000001  x22 0000000000000000  x23 0000000000000000
[        ]     x24 00000000ffffffe0  x25 0000000000000020  x26 0000000000000000  x27 0000007c06795f00
[        ]     x28 000000080000007c  x29 0000007fce23b820
[        ]     lr  0000007d80b46a6c  sp  0000007fce23b820  pc  0000007d80b46424  pst 0000000060000000
[        ] backtrace:
[        ]       #00 pc 0000000000135424  /vendor/lib64/hw/vulkan.adreno.so (!!!0000!08c664f899e474097c934ab231f22e!5eaa426211!+28) (BuildId: 2423be7c949412774885f0d6e72c67e6)
[        ]       #01 pc 0000000000135a68  /vendor/lib64/hw/vulkan.adreno.so (!!!0000!65bb4f16e1c4caf7a56f18c58bd23d!5eaa426211!+392) (BuildId: 2423be7c949412774885f0d6e72c67e6)
[        ]       #02 pc 0000000000074084  /vendor/lib64/hw/vulkan.adreno.so (qglinternal::vkBeginCommandBuffer(VkCommandBuffer_T*, VkCommandBufferBeginInfo const*)+140) (BuildId: 2423be7c949412774885f0d6e72c67e6)
[        ]       #03 pc 0000000001df4f08  /data/app/~~6lI5EAOfgoPUpeZnyGqcmg==/com.example.gpu_oom_repro-9esO5IJJmB9LwONnFPGdZg==/base.apk!libflutter.so (BuildId: cfed56bb2af0c4bb1edadfcd12315f98cad2643f)
[        ]       #04 pc 0000000001e91800  /data/app/~~6lI5EAOfgoPUpeZnyGqcmg==/com.example.gpu_oom_repro-9esO5IJJmB9LwONnFPGdZg==/base.apk!libflutter.so (InternalFlutterGpu_CommandBuffer_Initialize+60) (BuildId: cfed56bb2af0c4bb1edadfcd12315f98cad2643f)
[        ]       #05 pc 00000000000080f4  [anon:dart-code]
[+1826 ms] Service protocol connection closed.
[        ] Lost connection to device.
[   +1 ms] DevFS: Deleting filesystem on the device (file:///data/user/0/com.example.gpu_oom_repro/code_cache/gpu_oom_reproBOKKIS/gpu_oom_repro/)
[        ] DevFS: Deleted filesystem on the device (file:///data/user/0/com.example.gpu_oom_repro/code_cache/gpu_oom_reproBOKKIS/gpu_oom_repro/)
[   +2 ms] "flutter run" took 488,877ms.
[  +60 ms] Running 3 shutdown hooks
[  +11 ms] Shutdown hooks complete
[  +47 ms] exiting with code 0

Code sample

Code sample
import 'package:flutter/material.dart';
import 'package:flutter_gpu/gpu.dart' as gpu;

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  MyAppState createState() => MyAppState();
}

class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  @override
  void initState() {
    createTicker((elapsed) {
      setState(() {});
    }).start();

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My 3D app',
      home: CustomPaint(painter: TrianglePainter()),
    );
  }
}

class TrianglePainter extends CustomPainter {

  @override
  void paint(Canvas canvas, Size size) {

    final commandBuffer = gpu.gpuContext.createCommandBuffer();
    commandBuffer.submit();
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
https://gist.github.com/LordNed/093797e3622ec17e261ca4a3bd5d577e

Flutter Doctor output

Doctor output
 flutter doctor -v
[√] Flutter (Channel master, 3.33.0-1.0.pre.945, on Microsoft Windows [Version 10.0.19045.5965], locale en-US) [3.9s]
    • Flutter version 3.33.0-1.0.pre.945 on channel master at O:\code\flutter\flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 35f197f1e5 (12 hours ago), 2025-07-12 06:18:38 -0400
    • Engine revision 35f197f1e5
    • Dart version 3.9.0 (build 3.9.0-328.0.dev)
    • DevTools version 2.48.0
    • Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations, enable-native-assets

[√] Windows Version (10 Pro 64-bit, 22H2, 2009) [6.2s]

[√] Android toolchain - develop for Android devices (Android SDK version 36.0.0) [3.5s]
    • Android SDK at C:\Users\Matt\AppData\Local\Android\sdk
    • Emulator version 35.5.10.0 (build_id 13402964) (CL:N/A)
    • Platform android-36, build-tools 36.0.0
    • Java binary at: C:\Program Files\Android\Android Studio\jbr\bin\java
      This is the JDK bundled with the latest Android Studio installation on this machine.
      To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version OpenJDK Runtime Environment (build 21.0.6+-13368085-b895.109)
    • All Android licenses accepted.

[√] Chrome - develop for the web [195ms]
    • Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

[√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.13.2) [192ms]
    • Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Community
    • Visual Studio Community 2022 version 17.13.35825.156
    • Windows 10 SDK version 10.0.22621.0

[√] Android Studio (version 2024.3.2) [21ms]
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin can be installed from:
       https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
       https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 21.0.6+-13368085-b895.109)

[√] VS Code (version 1.102.0) [19ms]
    • VS Code at C:\Users\Matt\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.114.0

[√] Connected device (4 available) [952ms]
    • SM T500 (mobile)  • R9ARA02NMWF • android-arm64  • Android 12 (API 31)
    • Windows (desktop) • windows     • windows-x64    • Microsoft Windows [Version 10.0.19045.5965]
    • Chrome (web)      • chrome      • web-javascript • Google Chrome 138.0.7204.101
    • Edge (web)        • edge        • web-javascript • Microsoft Edge 137.0.3296.83

[√] Network resources [1,300ms]
    • All expected network resources are available.

• No issues found!
PS O:\code\flutter\flutter_gpu\

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projectengineflutter/engine related. See also e: labels.flutter-gpufound in release: 3.33Found to occur in 3.33has reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-androidAndroid applications specificallyr: fixedIssue is closed as already fixed in a newer versionteam-engineOwned by Engine teamtriaged-engineTriaged by Engine team

    Type

    No type

    Projects

    Status

    ✅ Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions