性能监控模块
📋 模块概述
性能监控模块用于实时监控H07应用的内存使用和CPU占用情况,帮助分析硬件降本的可行性。通过长期监控收集性能数据,可以评估当前硬件配置是否存在冗余,为硬件降本决策提供数据支持。
核心类:
android.znhaas.util.PerformanceMonitor- 性能监控工具android.znhaas.ui.screen.PerformanceMonitorScreen- 性能监控UI界面
监控指标:
- 💾 内存: Java堆、Native堆、PSS(Proportional Set Size)
- 🔥 CPU: 使用率、线程数
- 📊 统计: 平均值、峰值、警告次数
目标: 评估能否从当前配置(如2核16G)降低到1核8G,节省硬件成本。
🎯 主要功能
核心特性
- ✅ 实时监控 - 每5秒采样一次,实时跟踪性能指标
- ✅ 历史记录 - 保留最近1小时数据(720个数据点)
- ✅ 阈值报警 - 内存>512MB或CPU>50%时发出警告
- ✅ 性能报告 - 自动生成包含统计和建议的报告
- ✅ 硬件建议 - 基于实际使用率推荐最优硬件配置
- ✅ 数据导出 - 导出CSV格式数据用于进一步分析
- ✅ 可视化界面 - Jetpack Compose实现的实时监控界面
监控指标详解
内存指标
| 指标 | 说明 | 正常范围 |
|---|---|---|
| Total PSS | 进程实际占用内存(含共享内存按比例分摊) | < 512MB |
| Java Heap | Java虚拟机堆内存 | < 256MB |
| Native Heap | C/C++原生代码内存 | < 128MB |
| Dalvik PSS | Dalvik虚拟机内存 | - |
| Native PSS | 原生代码内存 | - |
| Graphics | 图形渲染内存(纹理、帧缓冲等) | < 100MB |
| Code | 代码段内存 | - |
| Stack | 线程栈内存 | - |
| Private Dirty | 私有脏页内存 | - |
CPU指标
| 指标 | 说明 | 正常范围 |
|---|---|---|
| CPU使用率 | 应用占用CPU百分比(单核100%) | < 50% |
| 线程数 | 应用活跃线程数量 | < 100 |
阈值定义
// 内存阈值
private const val MEMORY_WARNING_THRESHOLD_MB = 512 // 512MB警告
private const val MEMORY_CRITICAL_THRESHOLD_MB = 1024 // 1GB严重警告
// CPU阈值
private const val CPU_WARNING_THRESHOLD_PERCENT = 50 // 50%警告
private const val CPU_CRITICAL_THRESHOLD_PERCENT = 80 // 80%严重警告
📚 核心API
1. 获取PerformanceMonitor实例
val performanceMonitor = PerformanceMonitor.getInstance(context)
2. 开始监控
// 开始性能监控
performanceMonitor.startMonitoring()
// 日志输出:
// 📊 开始性能监控
// 📊 采样间隔: 5000ms
// 📊 保留数据点: 720 个
监控特性:
- 采样间隔: 5秒/次
- 数据保留: 最近720个数据点(1小时)
- 后台运行: 使用Kotlin协程在IO线程执行
- 自动阈值检查: 每次采样后自动检查是否超过阈值
3. 停止监控
// 停止性能监控
performanceMonitor.stopMonitoring()
4. 生成性能报告
// 生成性能报告
val report = performanceMonitor.generateReport()
// 报告内容:
println("报告时间: ${report.reportTime}")
println("监控时长: ${report.monitorDurationMinutes} 分钟")
println("平均内存: ${report.memoryStats.avgTotalMemoryMb} MB")
println("峰值内存: ${report.memoryStats.peakTotalMemoryMb} MB")
println("平均CPU: ${report.cpuStats.avgCpuPercent}%")
println("峰值CPU: ${report.cpuStats.peakCpuPercent}%")
println("是否可降本: ${report.hardwareRecommendation.canDowngrade}")
println("建议配置: ${report.hardwareRecommendation.recommendedCores}核 ${report.hardwareRecommendation.recommendedRamMb}MB")
性能报告数据结构:
data class PerformanceReport(
val reportTime: String, // 报告时间
val monitorDurationMinutes: Double, // 监控时长(分钟)
val memoryStats: MemoryStats, // 内存统计
val cpuStats: CpuStats, // CPU统计
val hardwareRecommendation: HardwareRecommendation // 硬件建议
)
data class MemoryStats(
val avgTotalMemoryMb: Double, // 平均总内存
val peakTotalMemoryMb: Double, // 峰值总内存
val avgJavaHeapMb: Double, // 平均Java堆
val peakJavaHeapMb: Double, // 峰值Java堆
val avgNativeHeapMb: Double, // 平均Native堆
val peakNativeHeapMb: Double, // 峰值Native堆
val memoryWarningCount: Int, // 内存警告次数
val memoryCriticalCount: Int // 内存严重警告次数
)
data class CpuStats(
val avgCpuPercent: Double, // 平均CPU使用率
val peakCpuPercent: Double, // 峰值CPU使用率
val avgThreadCount: Int, // 平均线程数
val peakThreadCount: Int, // 峰值线程数
val cpuWarningCount: Int, // CPU警告次数
val cpuCriticalCount: Int // CPU严重警告次数
)
data class HardwareRecommendation(
val canDowngrade: Boolean, // 是否可以降配
val recommendedRamMb: Int, // 建议内存(MB)
val recommendedCores: Int, // 建议CPU核心数
val reason: String, // 建议原因
val riskLevel: String // 风险等级: LOW/MEDIUM/HIGH
)
5. 获取实时快照
// 获取当前内存快照
val memorySnapshot = performanceMonitor.getCurrentMemorySnapshot()
if (memorySnapshot != null) {
println("当前内存使用: ${memorySnapshot.totalPssMb} MB")
println("Java堆: ${memorySnapshot.javaHeapUsedMb} / ${memorySnapshot.javaHeapMaxMb} MB")
println("Native堆: ${memorySnapshot.nativeHeapUsedMb} / ${memorySnapshot.nativeHeapMaxMb} MB")
}
// 获取当前CPU快照
val cpuSnapshot = performanceMonitor.getCurrentCpuSnapshot()
if (cpuSnapshot != null) {
println("当前CPU使用率: ${cpuSnapshot.cpuUsagePercent}%")
println("当前线程数: ${cpuSnapshot.threadCount}")
}
6. 导出数据到CSV
// 导出性能数据到CSV格式
val csvData = performanceMonitor.exportToCsv()
// 保存到文件
val file = File(context.cacheDir, "performance_data.csv")
file.writeText(csvData)
// CSV格式:
// timestamp,totalMemoryMb,javaHeapMb,nativeHeapMb,cpuPercent,threadCount
// 1737353000000,245,128,64,35,87
// 1737353005000,248,130,65,38,89
// ...
7. 清除历史数据
// 清除所有历史性能数据
performanceMonitor.clearHistory()
8. 获取系统内存信息
// 获取设备系统内存信息
val systemInfo = performanceMonitor.getSystemMemoryInfo()
println(systemInfo)
// 输出示例:
// 系统内存信息:
// 可用内存: 3456 MB
// 总内存: 8192 MB
// 低内存阈值: 512 MB
// 内存不足: false
🔧 工作原理
1. 监控流程
┌─────────────────────────────────────────────────────────┐
│ Step 1: 启动监控 │
│ - 初始化协程作业 │
│ - 初始化CPU时间基准 │
└───────────────┬─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Step 2: 定时采样 (每5秒) │
│ ├─ collectMemoryMetrics() │
│ │ ├─ Runtime.getRuntime() → Java堆 │
│ │ ├─ Debug.MemoryInfo() → PSS、Native堆 │
│ │ └─ 保存到memoryHistory队列 │
│ │ │
│ ├─ collectCpuMetrics() │
│ │ ├─ /proc/stat → 总CPU时间 │
│ │ ├─ /proc/$pid/stat → 应用CPU时间 │
│ │ ├─ 计算使用率 = (app_diff / total_diff) * 100 │
│ │ └─ 保存到cpuHistory队列 │
│ │ │
│ └─ checkThresholds() │
│ ├─ 内存 > 1024MB? → ⚠️ 严重警告 │
│ ├─ 内存 > 512MB? → ⚡ 警告 │
│ ├─ CPU > 80%? → ⚠️ 严重警告 │
│ └─ CPU > 50%? → ⚡ 警告 │
└───────────────┬─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Step 3: 生成报告 │
│ ├─ calculateMemoryStats() → 内存统计 │
│ ├─ calculateCpuStats() → CPU统计 │
│ ├─ generateHardwareRecommendation() → 硬件建议 │
│ └─ printReport() → 打印报告 │
└─────────────────────────────────────────────────────────┘
2. 内存指标采集
private fun collectMemoryMetrics() {
// 1. Java堆内存
val runtime = Runtime.getRuntime()
val javaHeapUsed = (runtime.totalMemory() - runtime.freeMemory()) / 1024.0 / 1024.0
val javaHeapMax = runtime.maxMemory() / 1024.0 / 1024.0
// 2. Native堆内存
val nativeHeapUsed = Debug.getNativeHeapAllocatedSize() / 1024.0 / 1024.0
val nativeHeapMax = Debug.getNativeHeapSize() / 1024.0 / 1024.0
// 3. PSS内存(包含共享内存按比例分摊)
val debugMemoryInfo = Debug.MemoryInfo()
Debug.getMemoryInfo(debugMemoryInfo)
val totalPss = debugMemoryInfo.totalPss / 1024.0
val dalvikPss = debugMemoryInfo.dalvikPss / 1024.0
val nativePss = debugMemoryInfo.nativePss / 1024.0
val graphicsPss = debugMemoryInfo.getMemoryStat("summary.graphics").toDoubleOrNull() ?: 0.0 / 1024.0
// 4. 创建内存快照
val snapshot = MemorySnapshot(
timestamp = System.currentTimeMillis(),
javaHeapUsedMb = javaHeapUsed,
javaHeapMaxMb = javaHeapMax,
nativeHeapUsedMb = nativeHeapUsed,
nativeHeapMaxMb = nativeHeapMax,
totalPssMb = totalPss,
dalvikPssMb = dalvikPss,
nativePssMb = nativePss,
graphicsPssMb = graphicsPss,
// ...
)
// 5. 保存到历史队列(FIFO,最多720个)
synchronized(memoryHistory) {
if (memoryHistory.size >= MAX_HISTORY_SIZE) {
memoryHistory.removeFirst()
}
memoryHistory.addLast(snapshot)
}
}
3. CPU指标采集
private fun collectCpuMetrics() {
// 1. 读取总CPU时间
val currentCpuTime = getTotalCpuTime() // 从/proc/stat读取
// 2. 读取应用CPU时间
val currentAppCpuTime = getAppCpuTime() // 从/proc/$pid/stat读取
// 3. 计算CPU使用率
if (lastCpuTime > 0 && currentCpuTime > lastCpuTime) {
val totalDiff = currentCpuTime - lastCpuTime
val appDiff = currentAppCpuTime - lastAppCpuTime
val cpuUsage = (appDiff.toDouble() / totalDiff.toDouble() * 100.0).coerceIn(0.0, 100.0)
}
// 4. 获取线程数
val threadCount = Thread.activeCount()
// 5. 保存快照
val snapshot = CpuSnapshot(
timestamp = System.currentTimeMillis(),
cpuUsagePercent = cpuUsage,
threadCount = threadCount
)
// 6. 更新基准时间
lastCpuTime = currentCpuTime
lastAppCpuTime = currentAppCpuTime
}
4. 硬件降本决策算法
private fun generateHardwareRecommendation(
memoryStats: MemoryStats,
cpuStats: CpuStats
): HardwareRecommendation {
// 1. 评估内存需求(添加30%安全余量)
val recommendedRamMb = ((memoryStats.peakTotalMemoryMb * 1.3).toInt() / 512 + 1) * 512
// 2. 评估CPU核心需求
val recommendedCores = when {
cpuStats.peakCpuPercent > 150 -> 2 // 峰值超过150%(多核),建议2核
cpuStats.avgCpuPercent > 75 -> 2 // 平均超过75%,建议2核
else -> 1 // 否则1核足够
}
// 3. 判断是否可以降本(目标: 1核8G)
val canDowngrade = recommendedRamMb <= 8192 && recommendedCores <= 1
// 4. 评估风险等级
val riskLevel = when {
memoryStats.peakTotalMemoryMb > 6144 || cpuStats.peakCpuPercent > 80 -> "HIGH"
memoryStats.peakTotalMemoryMb > 4096 || cpuStats.peakCpuPercent > 60 -> "MEDIUM"
else -> "LOW"
}
// 5. 生成建议
return HardwareRecommendation(
canDowngrade = canDowngrade,
recommendedRamMb = recommendedRamMb,
recommendedCores = recommendedCores,
reason = "...",
riskLevel = riskLevel
)
}
降本判断条件:
- ✅ 内存峰值 + 30%安全余量 ≤ 8GB
- ✅ CPU峰值 < 100% (单核足够)
- ✅ CPU平均 < 75%
风险评估:
- 🔴 HIGH: 内存峰值 > 6GB 或 CPU峰值 > 80%
- 🟡 MEDIUM: 内存峰值 > 4GB 或 CPU峰值 > 60%
- 🟢 LOW: 资源使用率较低,可安全降配
📊 性能报告示例
示例1: 可以降本的场景
═══════════════════════════════════════════════════════
📊 性能监控报告
═══════════════════════════════════════════════════════
⏱️ 报告时间: 2025-01-19 14:30:22
⏱️ 监控时长: 60 分钟
💾 内存使用情况:
平均总内存: 245 MB
峰值总内存: 356 MB
平均Java堆: 128 MB
峰值Java堆: 187 MB
平均Native堆: 64 MB
峰值Native堆: 92 MB
内存警告次数: 0
内存严重警告: 0
🔥 CPU使用情况:
平均CPU: 28%
峰值CPU: 45%
平均线程数: 87
峰值线程数: 112
CPU警告次数: 0
CPU严重警告: 0
🎯 硬件降本建议:
基于356MB峰值内存和45%峰值CPU使用率:
✅ 可以降低到 1核心8G 内存
- 实际内存峰值: 356MB
- 实际CPU峰值: 45%
- 建议配置: 1核心 512MB内存
风险评估: LOW
✅ 低风险:当前资源使用率较低,可以安全降配
═══════════════════════════════════════════════════════
示例2: 不建议降本的场景
═══════════════════════════════════════════════════════
📊 性能监控报告
═══════════════════════════════════════════════════════
⏱️ 报告时间: 2025-01-19 15:45:10
⏱️ 监控时长: 120 分钟
💾 内存使用情况:
平均总内存: 678 MB
峰值总内存: 1245 MB
平均Java堆: 345 MB
峰值Java堆: 589 MB
平均Native堆: 187 MB
峰值Native堆: 312 MB
内存警告次数: 45
内存严重警告: 12
🔥 CPU使用情况:
平均CPU: 68%
峰值CPU: 156%
平均线程数: 145
峰值线程数: 203
CPU警告次数: 87
CPU严重警告: 23
🎯 硬件降本建议:
基于1245MB峰值内存和156%峰值CPU使用率:
⚠️ 不建议降低配置
- 内存峰值1245MB超出8G限制
- CPU峰值156%需要2核心
- 建议配置: 2核心 2048MB内存
风险评估: HIGH
⚠️ 高风险:当前配置已接近极限,降配可能导致性能问题
═══════════════════════════════════════════════════════
📖 完整使用示例
示例1: 在Activity中集成性能监控
class MainActivity : AppCompatActivity() {
private lateinit var performanceMonitor: PerformanceMonitor
private val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 初始化性能监控
performanceMonitor = PerformanceMonitor.getInstance(this)
// 开始监控
performanceMonitor.startMonitoring()
Log.d(TAG, "性能监控已启动")
// 添加菜单项用于生成报告
btnGenerateReport.setOnClickListener {
generateAndShowReport()
}
}
/**
* 生成并显示性能报告
*/
private fun generateAndShowReport() {
val report = performanceMonitor.generateReport()
// 显示对话框
AlertDialog.Builder(this)
.setTitle("性能监控报告")
.setMessage(formatReport(report))
.setPositiveButton("导出CSV") { _, _ ->
exportCsvData()
}
.setNegativeButton("关闭", null)
.show()
}
/**
* 格式化报告为可读文本
*/
private fun formatReport(report: PerformanceMonitor.PerformanceReport): String {
return buildString {
appendLine("监控时长: ${report.monitorDurationMinutes.roundToInt()} 分钟")
appendLine()
appendLine("内存统计:")
appendLine(" 平均: ${report.memoryStats.avgTotalMemoryMb.roundToInt()} MB")
appendLine(" 峰值: ${report.memoryStats.peakTotalMemoryMb.roundToInt()} MB")
appendLine()
appendLine("CPU统计:")
appendLine(" 平均: ${report.cpuStats.avgCpuPercent.roundToInt()}%")
appendLine(" 峰值: ${report.cpuStats.peakCpuPercent.roundToInt()}%")
appendLine()
appendLine("硬件建议:")
if (report.hardwareRecommendation.canDowngrade) {
appendLine(" ✅ 可以降低到 1核心8G 内存")
} else {
appendLine(" ⚠️ 不建议降低配置")
}
appendLine(" 建议: ${report.hardwareRecommendation.recommendedCores}核 ${report.hardwareRecommendation.recommendedRamMb}MB")
appendLine(" 风险: ${report.hardwareRecommendation.riskLevel}")
}
}
/**
* 导出CSV数据
*/
private fun exportCsvData() {
val csvData = performanceMonitor.exportToCsv()
val file = File(getExternalFilesDir(null), "performance_${System.currentTimeMillis()}.csv")
file.writeText(csvData)
Toast.makeText(this, "CSV已导出: ${file.absolutePath}", Toast.LENGTH_LONG).show()
}
override fun onDestroy() {
super.onDestroy()
// 停止监控
performanceMonitor.stopMonitoring()
}
}
示例2: 使用Compose UI界面
@Composable
fun PerformanceMonitorScreen() {
val context = LocalContext.current
val performanceMonitor = remember { PerformanceMonitor.getInstance(context) }
val scope = rememberCoroutineScope()
var isMonitoring by remember { mutableStateOf(false) }
var currentMemory by remember { mutableStateOf<PerformanceMonitor.MemorySnapshot?>(null) }
var currentCpu by remember { mutableStateOf<PerformanceMonitor.CpuSnapshot?>(null) }
var performanceReport by remember { mutableStateOf<PerformanceMonitor.PerformanceReport?>(null) }
// 自动刷新UI
LaunchedEffect(isMonitoring) {
if (isMonitoring) {
while (true) {
currentMemory = performanceMonitor.getCurrentMemorySnapshot()
currentCpu = performanceMonitor.getCurrentCpuSnapshot()
delay(1000) // 每秒刷新
}
}
}
Column(modifier = Modifier.padding(16.dp)) {
// 控制按钮
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
Button(
onClick = {
if (isMonitoring) {
performanceMonitor.stopMonitoring()
isMonitoring = false
} else {
performanceMonitor.startMonitoring()
isMonitoring = true
}
}
) {
Text(if (isMonitoring) "停止监控" else "开始监控")
}
Button(
onClick = {
performanceReport = performanceMonitor.generateReport()
}
) {
Text("生成报告")
}
}
// 实时数据
if (isMonitoring) {
currentMemory?.let { mem ->
Card(modifier = Modifier.padding(top = 16.dp)) {
Column(modifier = Modifier.padding(16.dp)) {
Text("内存使用", fontWeight = FontWeight.Bold)
Text("总内存: ${mem.totalPssMb.roundToInt()} MB")
Text("Java堆: ${mem.javaHeapUsedMb.roundToInt()} MB")
Text("Native堆: ${mem.nativeHeapUsedMb.roundToInt()} MB")
}
}
}
currentCpu?.let { cpu ->
Card(modifier = Modifier.padding(top = 8.dp)) {
Column(modifier = Modifier.padding(16.dp)) {
Text("CPU使用", fontWeight = FontWeight.Bold)
Text("CPU: ${cpu.cpuUsagePercent.roundToInt()}%")
Text("线程: ${cpu.threadCount}")
}
}
}
}
// 性能报告
performanceReport?.let { report ->
Card(
modifier = Modifier.padding(top = 16.dp),
colors = CardDefaults.cardColors(
containerColor = when (report.hardwareRecommendation.riskLevel) {
"HIGH" -> Color(0xFFFFEBEE)
"MEDIUM" -> Color(0xFFFFF9C4)
else -> Color(0xFFE8F5E9)
}
)
) {
Column(modifier = Modifier.padding(16.dp)) {
Text("性能报告", fontWeight = FontWeight.Bold, fontSize = 18.sp)
Text("监控时长: ${report.monitorDurationMinutes.roundToInt()} 分钟")
Spacer(modifier = Modifier.height(8.dp))
Text("峰值内存: ${report.memoryStats.peakTotalMemoryMb.roundToInt()} MB")
Text("峰值CPU: ${report.cpuStats.peakCpuPercent.roundToInt()}%")
Spacer(modifier = Modifier.height(8.dp))
Text(
text = if (report.hardwareRecommendation.canDowngrade)
"✅ 可以降低到 1核8G"
else
"⚠️ 不建议降低配置",
fontWeight = FontWeight.Bold,
color = if (report.hardwareRecommendation.canDowngrade)
Color(0xFF2E7D32)
else
Color(0xFFC62828)
)
Text("建议: ${report.hardwareRecommendation.recommendedCores}核 ${report.hardwareRecommendation.recommendedRamMb}MB")
Text("风险: ${report.hardwareRecommendation.riskLevel}")
}
}
}
}
}
示例3: 定时监控并自动报告
class PerformanceMonitorService : Service() {
private lateinit var performanceMonitor: PerformanceMonitor
private lateinit var logUtil: LogUtil
private val scope = CoroutineScope(Dispatchers.Default + SupervisorJob())
override fun onCreate() {
super.onCreate()
performanceMonitor = PerformanceMonitor.getInstance(this)
logUtil = LogUtil.getInstance(this)
// 开始监控
performanceMonitor.startMonitoring()
// 每小时生成一次报告
scope.launch {
while (isActive) {
delay(60 * 60 * 1000) // 1小时
generateAndLogReport()
}
}
}
private fun generateAndLogReport() {
val report = performanceMonitor.generateReport()
// 记录到日志
logUtil.i("PerformanceService", "=" .repeat(50))
logUtil.i("PerformanceService", "定时性能报告")
logUtil.i("PerformanceService", "时间: ${report.reportTime}")
logUtil.i("PerformanceService", "内存峰值: ${report.memoryStats.peakTotalMemoryMb.roundToInt()} MB")
logUtil.i("PerformanceService", "CPU峰值: ${report.cpuStats.peakCpuPercent.roundToInt()}%")
logUtil.i("PerformanceService", "可降本: ${report.hardwareRecommendation.canDowngrade}")
logUtil.i("PerformanceService", "=" .repeat(50))
// 如果发现可以降本,发送通知
if (report.hardwareRecommendation.canDowngrade) {
sendNotification("硬件降本建议", "当前配置可以降低到1核8G,节省成本")
}
}
private fun sendNotification(title: String, message: String) {
val notification = NotificationCompat.Builder(this, "performance")
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(R.drawable.ic_notification)
.build()
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.notify(1, notification)
}
override fun onDestroy() {
super.onDestroy()
performanceMonitor.stopMonitoring()
scope.cancel()
}
override fun onBind(intent: Intent?): IBinder? = null
}
🔧 注意事项
1. 数据准确性
- ⏱️ 采样间隔: 5秒采样可能遗漏瞬时峰值,建议长时间监控(≥1小时)
- 📊 PSS vs RSS: PSS(Proportional Set Size)更准确反映实际内存占用
- 🔥 CPU计算: 基于
/proc文件系统,需要Linux内核支持
2. 性能影响
性能监控本身也会消耗资源:
- 💾 内存: 约增加2-5MB (存储720个数据点)
- 🔥 CPU: 每次采样约占用1-2%CPU (5秒一次)
- 📁 存储: CSV导出文件约100-500KB
3. 权限要求
<!-- 不需要额外权限,使用标准Android API -->
4. 线程安全
// 所有历史数据都使用synchronized保护
synchronized(memoryHistory) {
if (memoryHistory.size >= MAX_HISTORY_SIZE) {
memoryHistory.removeFirst()
}
memoryHistory.addLast(snapshot)
}
5. 内存泄漏预防
// Activity销毁时务必停止监控
override fun onDestroy() {
super.onDestroy()
performanceMonitor.stopMonitoring()
}
6. CSV数据格式
timestamp,totalMemoryMb,javaHeapMb,nativeHeapMb,cpuPercent,threadCount
1737353000000,245,128,64,35,87
1737353005000,248,130,65,38,89
1737353010000,250,132,66,42,91
可以导入Excel或Python进行进一步分析:
import pandas as pd
import matplotlib.pyplot as plt
# 读取CSV
df = pd.read_csv('performance_data.csv')
df['datetime'] = pd.to_datetime(df['timestamp'], unit='ms')
# 绘制内存趋势图
plt.figure(figsize=(12, 6))
plt.plot(df['datetime'], df['totalMemoryMb'], label='Total Memory')
plt.plot(df['datetime'], df['javaHeapMb'], label='Java Heap')
plt.plot(df['datetime'], df['nativeHeapMb'], label='Native Heap')
plt.xlabel('Time')
plt.ylabel('Memory (MB)')
plt.title('Memory Usage Over Time')
plt.legend()
plt.show()
# 绘制CPU趋势图
plt.figure(figsize=(12, 6))
plt.plot(df['datetime'], df['cpuPercent'], label='CPU Usage', color='red')
plt.xlabel('Time')
plt.ylabel('CPU (%)')
plt.title('CPU Usage Over Time')
plt.axhline(y=50, color='orange', linestyle='--', label='Warning Threshold')
plt.axhline(y=80, color='red', linestyle='--', label='Critical Threshold')
plt.legend()
plt.show()
📖 相关资源
源码位置
- PerformanceMonitor:
app/src/main/java/android/znhaas/util/PerformanceMonitor.kt - PerformanceMonitorScreen:
app/src/main/java/android/znhaas/ui/screen/PerformanceMonitorScreen.kt
依赖库
// app/build.gradle.kts
dependencies {
// Kotlin协程
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
// Jetpack Compose (UI界面)
implementation("androidx.compose.ui:ui:1.5.0")
implementation("androidx.compose.material3:material3:1.1.0")
}
相关文档
最后更新: 2025-01-19
文档版本: v1.0
基于代码版本: H07 Android App (main分支)