文章用来记录及分享本人对安卓程序中内存使用的个人见解,如有不同见解 不吝赐教。

先简单浏览下面代码,看看对它们是否熟悉

               val activityManager = getSystemService(ACTIVITY_SERVICE) as ActivityManager
                // Java 堆内存信息
                val runtime = Runtime.getRuntime()
                val usedMemory = (runtime.totalMemory() - runtime.freeMemory()) / 1024 / 1024
                val maxMemory = runtime.maxMemory() / 1024 / 1024

                //todo Native内存和Java(Dalvik/ART)内存是分开的

                val memoryInfo = ActivityManager.MemoryInfo()
                activityManager.getMemoryInfo(memoryInfo)

                // 获取系统内存信息
                // 获取应用最大可使用内存,标准模式和大内存模式

                //应用在Dalvik/ART虚拟机中可以分配的最大内存。
                val memoryClassMb = activityManager.memoryClass

                //用于那些需要更多内存的应用,表示在大内存设备上应用可以使用的内存预算。
                val largeMemoryClassMb = activityManager.largeMemoryClass

                //系统总内存
                val totalMemoryMb = memoryInfo.totalMem / 1024 / 1024
                //系统可用内存
                val availMemoryMb = memoryInfo.availMem / 1024 / 1024
                //系统已用内存
                val usedMemoryMb = totalMemoryMb - availMemoryMb

                val lowMemory = memoryInfo.lowMemory

                Log.d(TAG, "系统总内存: $totalMemoryMb MB \n" +
                        "系统可用内存: $availMemoryMb MB\n" +
                        "系统已用内存: $usedMemoryMb MB\n" +
                        "应用最大可使用内存 (标准模式): ${memoryClassMb}MB\n" +
                        "应用最大可使用内存 (大内存模式): ${largeMemoryClassMb}MB")


                val debugMemoryInfo : Debug.MemoryInfo = Debug.MemoryInfo()
                Debug.getMemoryInfo(debugMemoryInfo)

                //当前程序的总内存使用量(以 MB 为单位)(包括 Java 堆、Native 堆以及其他内存使用,整个进程的总内存使用)
                val totalPssMb = debugMemoryInfo.totalPss.toLong() / 1024

                // 当前进程在 native 层可用的总堆内存大小(以 MB 为单位)
                val nativeHeapSize: Long = Debug.getNativeHeapSize() / 1024 / 1024

                //当进程中native层中已使用堆内存(以 MB 为单位)
                val useNative : Long = Debug.getNativeHeapAllocatedSize() / 1024 / 1024

                //当前进程中native层中剩余的堆内存(以 MB 为单位)
                val freeNative = Debug.getNativeHeapFreeSize() / 1024 / 1024


                // 计算当前应用剩余可用的内存
                val maxMemoryClassMb = if (largeMemoryClassMb > memoryClassMb) largeMemoryClassMb else memoryClassMb
                val remainingMemoryMb = maxMemoryClassMb - totalPssMb

                // 检查是否接近内存上限
                val isMemoryLow = usedMemory > maxMemory * 0.8 || useNative > nativeHeapSize * 0.8 || lowMemory

在开发安卓应用时,内存管理一直是一个关键的考虑因素。良好的内存管理不仅可以提高应用的性能,还能避免内存泄漏和崩溃,由于项目所需,特来恶补相关知识。

1. Java 堆内存

Java 堆内存是 JVM 分配给应用的内存,主要用于分配对象。通过 Runtime.getRuntime() 可以获取和管理 JVM 的堆内存信息。

val runtime = Runtime.getRuntime()
val usedMemory = (runtime.totalMemory() - runtime.freeMemory()) / 1024 / 1024
val maxMemory = runtime.maxMemory() / 1024 / 1024
  • 已用内存(usedMemory):当前应用已经使用的堆内存。
  • 最大内存(maxMemory):JVM 能够使用的最大内存。

注意事项

  • 避免内存泄漏:确保不再使用的对象能及时被垃圾回收,避免持有不必要的引用。
  • 合理分配内存:尽量减少大对象的使用,优化数据结构以节省内存。

2. 系统内存

系统内存是整个设备的内存,包括所有运行的应用和系统服务。通过 ActivityManager可以获取设备的系统内存信息。

val memoryInfo = ActivityManager.MemoryInfo()
activityManager.getMemoryInfo(memoryInfo)

val totalMemoryMb = memoryInfo.totalMem / 1024 / 1024
val availMemoryMb = memoryInfo.availMem / 1024 / 1024
val usedMemoryMb = totalMemoryMb - availMemoryMb
val lowMemory = memoryInfo.lowMemory
  • 系统总内存(totalMemoryMb):设备的总内存。
  • 系统可用内存(availMemoryMb):设备当前可用的内存。
  • 系统已用内存(usedMemoryMb):设备当前已使用的内存。
  • 低内存标志(lowMemory):系统是否处于低内存状态。

注意事项

  • 在低内存状态下,系统可能会回收后台应用的内存以确保前台应用正常运行。开发者应适当释放资源,避免应用被系统强制终止。

3. 应用内存配额

安卓系统对每个应用分配了内存配额,标准模式和大内存模式下的内存配额有所不同。

val memoryClassMb = activityManager.memoryClass
val largeMemoryClassMb = activityManager.largeMemoryClass
  • 标准模式内存配额(memoryClassMb):应用在标准模式下最大可使用的内存。
  • 大内存模式内存配额(largeMemoryClassMb):应用在大内存模式下最大可使用的内存。

注意事项

  • 合理选择内存模式:对于需要大量内存的应用,可以申请大内存模式,但要确保设备支持。

4. 进程内存信息

通过 Debug.MemoryInfo 可以获取当前进程的内存使用情况,包括 Java 堆、Native 堆以及其他类型的内存使用。

val debugMemoryInfo : Debug.MemoryInfo = Debug.MemoryInfo()
Debug.getMemoryInfo(debugMemoryInfo)

val totalPssMb = debugMemoryInfo.totalPss.toLong() / 1024
  • 总 PSS 内存(totalPssMb):当前应用进程的总内存使用量,一般程序使用内存情况就看这个数据。

5. Native 层内存

除了 Java 堆,应用还会使用 Native 层的内存。通过 Debug 类可以获取 Native 堆内存信息。

val nativeHeapSize: Long = Debug.getNativeHeapSize() / 1024 / 1024
val useNative : Long = Debug.getNativeHeapAllocatedSize() / 1024 / 1024
val freeNative = Debug.getNativeHeapFreeSize() / 1024 / 1024
  • Native 堆大小(nativeHeapSize):当前进程在 Native 层可用的总堆内存。
  • 已使用的 Native 内存(useNative):当前进程中 Native 层已使用的堆内存。
  • 剩余的 Native 内存(freeNative):当前进程中 Native 层剩余的堆内存。

注意事项

  • 避免 Native 内存泄漏:使用 C/C++ 编写的代码要特别注意内存管理,确保分配的内存在使用后能及时释放。

先写到这,后续深入了解后再继续补充
下班,端午快乐~

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部