Appearance
内存优化
鸿蒙内存管理:内存泄漏检测、GC 优化、大对象处理、图片内存控制。
1. 内存模型
1.1 内存分布
应用内存分布
├─ 堆内存(Heap)
│ ├─ 对象实例
│ ├─ 数组
│ └─ 大对象(图片、视频)
├─ 栈内存(Stack)
│ ├─ 局部变量
│ └─ 函数调用栈
└─ 原生内存(Native)
├─ C++ 对象
└─ 图形缓冲区1.2 内存限制
| 设备类型 | 内存限制 | 警告阈值 |
|---|---|---|
| 低端机(2-4GB) | 256MB | 200MB |
| 中端机(4-8GB) | 512MB | 400MB |
| 高端机(8GB+) | 1GB | 800MB |
2. 内存泄漏检测
2.1 常见泄漏场景
typescript
// ❌ 错误:闭包引用导致泄漏
class BadComponent {
private timer: number | null = null
private data: any = null
start() {
this.timer = setInterval(() => {
// 闭包引用了 this,导致组件无法释放
this.data = loadData()
}, 1000)
}
// 忘记清理定时器
// aboutToDisappear() 中未清除
}
// ✅ 正确:及时清理
class GoodComponent {
private timer: number | null = null
private data: any = null
start() {
this.timer = setInterval(() => {
this.data = loadData()
}, 1000)
}
aboutToDisappear() {
// 清理定时器
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
// 释放大对象
this.data = null
}
}2.2 事件监听泄漏
typescript
// ❌ 错误:未移除事件监听
class BadComponent {
aboutToAppear() {
eventHub.on('customEvent', this.handleEvent.bind(this))
// 组件销毁后监听仍存在
}
}
// ✅ 正确:成对注册/移除
class GoodComponent {
private handler: (e: any) => void = (e) => this.handleEvent(e)
aboutToAppear() {
eventHub.on('customEvent', this.handler)
}
aboutToDisappear() {
eventHub.off('customEvent', this.handler)
}
}3. 图片内存优化
3.1 图片缩放
typescript
// ❌ 错误:加载原图(可能 10MB+)
Image($r('app.media.large_image'))
.width(100)
.height(100)
// 虽然显示 100x100,但内存中是原图大小
// ✅ 正确:使用缩略图
Image($r('app.media.large_image_thumbnail'))
.width(100)
.height(100)
// 缩略图只有 50KB,内存占用小 200 倍3.2 图片缓存
typescript
class ImageCache {
private cache: LruCache<string, imagePixel.ImagePixel> = new LruCache(50)
// 获取缓存图片
get(url: string): imagePixel.ImagePixel | null {
return this.cache.get(url) || null
}
// 设置缓存
put(url: string, pixel: imagePixel.ImagePixel): void {
this.cache.put(url, pixel)
}
// 清理缓存
clear(): void {
this.cache.clear()
}
}4. GC 优化
4.1 减少 GC 压力
typescript
// ❌ 错误:频繁创建对象
function badLoop() {
for (let i = 0; i < 10000; i++) {
let obj = { id: i, name: `item_${i}` } // 每次循环创建新对象
process(obj)
}
}
// ✅ 正确:复用对象
function goodLoop() {
let obj = { id: 0, name: '' }
for (let i = 0; i < 10000; i++) {
obj.id = i
obj.name = `item_${i}` // 复用同一对象
process(obj)
}
}4.2 大对象处理
typescript
// ❌ 错误:大对象长期持有
class BadClass {
private largeData: ArrayBuffer | null = null
loadData() {
this.largeData = new ArrayBuffer(100 * 1024 * 1024) // 100MB
// 用完不释放
}
}
// ✅ 正确:用完即释放
class GoodClass {
private largeData: ArrayBuffer | null = null
async loadData() {
this.largeData = new ArrayBuffer(100 * 1024 * 1024)
try {
// 使用数据
await process(this.largeData)
} finally {
// 用完释放
this.largeData = null
}
}
}5. 内存监控
5.1 内存使用监控
typescript
import { systemMemoryInfo } from '@kit.SystemKit'
// 获取内存信息
let memInfo = systemMemoryInfo.getMemoryInfo()
console.log('总内存:', memInfo.totalMemory)
console.log('可用内存:', memInfo.availableMemory)
console.log('已用内存:', memInfo.usedMemory)
// 内存警告监听
systemMemoryInfo.on('memoryWarning', (level: number) => {
if (level === systemMemoryInfo.MemoryLevel.CRITICAL) {
// 紧急清理缓存
this.clearCache()
}
})6. 面试高频考点
Q1: 内存泄漏常见原因?
回答:定时器未清理、事件监听未移除、闭包引用、大对象长期持有、单例持有 Activity 引用。
Q2: 图片内存如何优化?
回答:使用缩略图而非原图、指定宽高、LruCache 缓存、及时释放。
🐱 小猫提示:内存优化记住 "定时器清理、监听移除、缩略图、LruCache、大对象及时释放"。