在响应 trim 事件时,最好释放不需要立即使用但可以按需重建的大内存分配。例如,如果您的应用具有从本地存储的压缩图片解码而来的位图缓存,那么通常最好在响应 TRIM_MEMORY_UI_HIDDEN 时剪裁或清除此缓存。
Kotlin
classMainActivity:AppCompatActivity(),ComponentCallbacks2{overridefunonTrimMemory(level:Int){if(level>=ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN){// Release memory related to UI elements, such as bitmap caches.}if(level>=ComponentCallbacks2.TRIM_MEMORY_BACKGROUND){// Release memory related to background processing, such as by// closing a database connection.}}}
Java
publicclassMainActivityextendsAppCompatActivityimplementsComponentCallbacks2{publicvoidonTrimMemory(intlevel){switch(level){if(level>=ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN){// Release memory related to UI elements, such as bitmap caches.}if(level>=ComponentCallbacks2.TRIM_MEMORY_BACKGROUND){// Release memory related to background processing, such as by// closing a database connection.}}}}
C#
usingUnityEngine;usingSystem.Collections;usingSystem.Collections.Generic;classLowMemoryTrigger:MonoBehaviour{privatevoidStart(){Application.lowMemory+=OnLowMemory;}privatevoidOnLowMemory(){// Respond to low memory condition (e.g., Resources.UnloadUnusedAssets())}}
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-08-26。"],[],[],null,["# Manage memory effectively in games\n\nOn the Android platform, the system tries to use as much system memory (RAM) as\npossible and performs various memory optimizations to free up space when needed.\nThese optimizations can have a negative effect on your game, either by slowing\nit down or killing it altogether. You can learn more about these optimizations\nin the topic\n[Memory allocation among processes](/topic/performance/memory-management).\n\nThis page explains the steps you can take to avoid low memory conditions\naffecting your game.\n\nRespond to onTrimMemory()\n-------------------------\n\nThe system uses\n[`onTrimMemory()`](/reference/android/content/ComponentCallbacks2#onTrimMemory(int))\nto notify your app of lifecycle events that present a good opportunity for your\napp to voluntarily reduce its memory usage and avoid being killed by the\n[low-memory killer (LMK)](/topic/performance/memory-management#low-memory_killer)\nto release memory for other apps to use.\n\nIf your app is killed in the background, then the next time the user launches\nyour app they will experience a slow\n[cold start](/topic/performance/vitals/launch-time#cold). Apps that reduce their\nmemory usage when going to the background are less likely to be killed in the\nbackground.\n\nWhen responding to trim events, it's best to release large memory allocations\nthat are not immediately needed and could be reconstructed on demand. For\nexample, if your app has a cache of bitmaps that were decoded from locally\nstored compressed images, then it's often a good idea to trim or purge this\ncache in response to\n[`TRIM_MEMORY_UI_HIDDEN`](/reference/android/content/ComponentCallbacks2#TRIM_MEMORY_UI_HIDDEN). \n\n### Kotlin\n\n```kotlin\nclass MainActivity : AppCompatActivity(), ComponentCallbacks2 {\n override fun onTrimMemory(level: Int) {\n if (level \u003e= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {\n // Release memory related to UI elements, such as bitmap caches.\n }\n if (level \u003e= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) {\n // Release memory related to background processing, such as by\n // closing a database connection.\n }\n }\n}\n```\n\n### Java\n\n```java\npublic class MainActivity extends AppCompatActivity implements ComponentCallbacks2 {\n public void onTrimMemory(int level) {\n switch (level) {\n if (level \u003e= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {\n // Release memory related to UI elements, such as bitmap caches.\n }\n if (level \u003e= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) {\n // Release memory related to background processing, such as by\n // closing a database connection.\n }\n }\n }\n}\n```\n\n### C#\n\n```c#\nusing UnityEngine;\nusing System.Collections;\nusing System.Collections.Generic;\n\nclass LowMemoryTrigger : MonoBehaviour\n{\n private void Start()\n {\n Application.lowMemory += OnLowMemory;\n }\n private void OnLowMemory()\n {\n // Respond to low memory condition (e.g., Resources.UnloadUnusedAssets())\n }\n}\n```\n\nUse the Memory Advice API beta\n------------------------------\n\nThe [Memory Advice API](/games/sdk/memory-advice/overview) was developed as an\nalternative to onTrimMemory that has much higher recall and precision at\npredicting impending LMKs. The API achieves this by estimating the amount of\nmemory resources that are in use, and then notifying the app when certain\nthresholds are exceeded. The API can also report the estimated percentage of\nmemory use directly to your app. You can use the Memory Advice API as an\nalternative to\n[`onTrimMemory`](/reference/android/content/ComponentCallbacks2#onTrimMemory(int))\nevents for the purpose of memory management.\n\nTo use the Memory Advice API use the\n[getting started guide.](/games/sdk/memory-advice/start)\n\nBe conservative with memory budgets\n-----------------------------------\n\nBudget memory conservatively to avoid running out of memory. Some items to\nconsider include the following:\n\n- **Size of physical RAM**: Games often use between ¼ and ½ of the physical RAM amount on the device.\n- **Maximum zRAM size** : More zRAM means the game potentially has more memory to allocate. This amount can vary based on device; look for `SwapTotal` in `/proc/meminfo` to find this value.\n- **Memory usage of the OS**: Devices that designate more RAM to system processes leave less memory for your game. The system kills your game's process before it kills system processes.\n- **Memory usage of installed apps**: Test your game on devices that have many apps installed. Social media and chat apps need to run constantly and affect the amount of free memory.\n\nIf you can't commit to a conservative memory budget, take a more flexible\napproach. If the system runs into low memory issues, reduce the amount of memory\nthat the game is using. For example, allocate lower-resolution textures or store\nfewer shaders in response to `onTrimMemory()`. This dynamic approach to memory\nallocation requires more work from the developer, especially in the game design\nphase.\n\nAvoid thrashing\n---------------\n\n*Thrashing* occurs when free memory is low, but not low enough to kill the game.\nIn this situation, `kswapd` has reclaimed pages that the game still needs, so it\ntries to reload the pages from memory. There isn't enough space, so the pages\nkeep getting swapped out (continuous swapping).\n[System tracing](/topic/performance/tracing) reports this situation as a thread\nwhere `kswapd` runs continuously.\n\nOne symptom of thrashing is long frame times - possibly a second or more. Reduce\nthe memory footprint of the game to resolve this situation.\n\nUse available tools\n-------------------\n\nAndroid has a collection of tools to assist in understanding how the system\nmanages memory.\n\n### Meminfo\n\nThis tool collects memory statistics to show how much\n[PSS memory](/topic/performance/memory-management#calculating_memory_footprint)\nwas allocated and the categories for which it was used.\n\nPrint the [meminfo](/studio/command-line/dumpsys#meminfo) statistics in one of\nthe following ways:\n\n- Use the command `adb shell dumpsys meminfo\n `\u003cvar translate=\"no\"\u003epackage-name\u003c/var\u003e.\n- Use the [`MemoryInfo`](/reference/android/os/Debug.MemoryInfo) call from the Android Debug API.\n\nThe [`PrivateDirty`](/studio/command-line/dumpsys#meminfo) statistic shows the\namount of RAM inside the process that can not be paged to disk and is not shared\nwith any other processes. The bulk of this amount becomes available to the\nsystem when that process is killed.\n\n### Memory tracepoints\n\nMemory tracepoints track the amount of\n[RSS memory](/topic/performance/memory-management#calculating_memory_footprint)\nyour game is using. Calculating RSS memory usage is much faster than calculating\nPSS usage. Because it's faster to calculate, RSS shows finer granularity on\nchanges in the memory size for more accurate measurements of peak memory usage.\nTherefore, it's easier to notice peaks that could cause the game to run out of\nmemory.\n\n#### Perfetto and long traces\n\n[Perfetto](https://docs.perfetto.dev) is a suite of tools for collecting\nperformance and memory information on a device and displaying in a web-based UI.\nIt supports arbitrarily long traces so you can view how RSS changes over time.\nYou can also issue SQL queries on the data it produces for offline processing.\nEnable long traces from the\n[System Tracing app](/topic/performance/tracing/on-device). Make sure the\n**memory:Memory** category is enabled for the trace.\n\n### heapprofd\n\n[`heapprofd`](https://docs.perfetto.dev/#/heapprofd) is a memory tracking tool\nthat's part of Perfetto. This tool can help you find memory leaks by showing\nwhere memory was allocated using `malloc`. `heapprofd` can be started using a\nPython script, and because the tool has low overhead, it doesn't affect\nperformance like other tools such as Malloc Debug.\n| **Note:** Since game engines use `mmap` with the `MAP_ANONYMOUS` flag to create memory pools, most allocations are not tracked. If you have access to the game engine source code, replace the memory pool `mmap` calls with `malloc`. Some game engines have an option to use `malloc` instead of `mmap`.\n\n### bugreport\n\n`bugreport` is a logging tool for finding out whether or not your game crashed\nbecause it ran out of memory. The tool's output is much more detailed than using\nlogcat. It's useful for memory debugging because it shows if your game crashed\nbecause it ran out of memory or if it was killed by the LMK.\n\nFor more information, see\n[Capture and read bug reports](/studio/debug/bug-report)."]]