Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách phát hiện kích thước Heap ứng dụng Android bằng Kotlin

Giới thiệu

Hướng dẫn này trình bày cách lấy kích thước heap memory (bộ nhớ heap) tối đa mà ứng dụng Android được cấp phép sử dụng, thông qua ActivityManager.getMemoryClass() và Kotlin.

Các bước thực hiện

Bước 1: Tạo dự án mới

Tạo project: File → New Project.

Bước 2: Thiết kế giao diện (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="50dp"
        android:text="Tutorials Point"
        android:textAlignment="center"
        android:textColor="@android:color/holo_green_dark"
        android:textSize="32sp"
        android:textStyle="bold" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:onClick="getHeapSize"
        android:text="Detect Heap Size" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button"
        android:layout_centerInParent="true"
        android:layout_marginTop="20dp"
        android:textColor="@android:color/holo_red_light"
        android:textSize="24sp"
        android:textStyle="bold" />

</RelativeLayout>

Bước 3: Xử lý logic (src/MainActivity.kt)

import android.app.ActivityManager
import android.content.Context
import android.os.Bundle
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    private lateinit var textView: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        title = "KotlinApp"

        textView = findViewById(R.id.textView)
    }

    fun getHeapSize(view: View) {
        val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        val memoryClass = activityManager.memoryClass // Trả về MB
        textView.text = "Heap Size: $memoryClass MB"
    }
}

Bước 4: Cấu hình Manifest (androidManifest.xml)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.com.q11">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>

Chạy ứng dụng

Kết nối thiết bị, nhấn Run. Nhấn nút "Detect Heap Size" sẽ hiển thị heap size tối đa (ví dụ: 256 MB, 512 MB, 1024 MB tùy thiết bị).

Giải thích

  • ActivityManager.memoryClass: Trả về heap size tối đa cho ứng dụng (dalvik/art heap) tính bằng Megabytes (MB).
  • Giá trị này được định nghĩa bởi thiết bị (manufacturer) và không thể thay đổi bởi app.
  • App vượt quá giới hạn này sẽ bị OutOfMemoryError.

Mở rộng: Thông tin bộ nhớ chi tiết

fun getDetailedMemoryInfo() {
    val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    
    // Heap size limit
    val maxMemory = Runtime.getRuntime().maxMemory() / (1024 * 1024) // MB
    val totalMemory = Runtime.getRuntime().totalMemory() / (1024 * 1024)
    val freeMemory = Runtime.getRuntime().freeMemory() / (1024 * 1024)
    
    // Memory info hệ thống
    val memInfo = ActivityManager.MemoryInfo()
    activityManager.getMemoryInfo(memInfo)
    val availMem = memInfo.availMem / (1024 * 1024)
    val totalMem = memInfo.totalMem / (1024 * 1024)
    val threshold = memInfo.threshold / (1024 * 1024)
    val lowMemory = memInfo.lowMemory
    
    val builder = StringBuilder().apply {
        appendLine("=== App Heap (Runtime) ===")
        appendLine("Max Heap: ${maxMemory} MB")
        appendLine("Total Allocated: ${totalMemory} MB")
        appendLine("Free: ${freeMemory} MB")
        appendLine("Used: ${totalMemory - freeMemory} MB")
        appendLine("\n=== System Memory (ActivityManager) ===")
        appendLine("Available: ${availMem} MB")
        appendLine("Total: ${totalMem} MB")
        appendLine("Low Memory Threshold: ${threshold} MB")
        appendLine("Is Low Memory: $lowMemory")
        appendLine("\n=== ActivityManager Memory Class ===")
        appendLine("Memory Class: ${activityManager.memoryClass} MB")
        appendLine("Large Memory Class: ${activityManager.largeMemoryClass} MB")
    }
    
    textView.text = builder.toString()
}

Large Heap

Nếu app cần nhiều memory hơn (xử lý ảnh lớn, video), có thể khai báo trong Manifest:

<application
    android:largeHeap="true"
    ... >

Khi đó, activityManager.largeMemoryClass sẽ trả về giới hạn lớn hơn. Tuy nhiên:

  • Chỉ dùng khi thực sự cần thiết (xử lý bitmap lớn).
  • GC (Garbage Collection) sẽ chậm hơn do heap lớn.
  • Không phải thiết bị nào cũng cấp large heap.

Lưu ý

  • Runtime.getRuntime().maxMemory() thường bằng memoryClass * 1024 * 1024.
  • Trên Android 8.0+, hệ thống quản lý memory chặt chẽ hơn.
  • Dùng LeakCanary hoặc Android Profiler để debug memory leak thực tế.