Android 垃圾回收器(GC)

本文解析了几种常见的GC类型,包括GC_CONCURRENT、GC_FOR_MALLOC等,并详细介绍了每种GC触发的原因及其运行机制。此外,还介绍了如何通过GC日志来理解堆内存的使用情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GC_XXX表明是哪类GC以及触发GC的原因。几种GC类型:
- GC_CONCURRENT:这是因为你的heap内存占用开始往上涨了,为了避免heap内存满了而触发执行的。
- GC_FOR_MALLOC:这是由于concurrent gc没有及时执行完而你的应用又需要分配更多的内存,内存要满了,这个时候不得不停下来进行malloc gc。
- GC_EXTERNAL_ALLOC:这是为external分配的内存执行的GC。
- GC_HPROF_DUMP_HEAP:这是当你做HPROF这样一个操作去创建一个HPROF profile的时候执行的。

- GC_EXPLICIT:这是由于你显式的调用了System.gc(),这是不提倡的,一般来说我们可以信任系统的GC。

freed 2049K表明在这次GC中回收了多少内存。
65% free 3571K/9991K是heap的一些统计数据,表明这次回收后65%的heap可用,存活的对象大小3571K,heap大小是9991K。
external 4703K/5261K是Native Memory的数据。放Bitmap Pixel Data或者是NIO Direct Buffer之类的。第一个数字表明Native Memory中已分配了多少内存,第二个值有点类似一个浮动的阀值,表明分配内存达到这个值系统就会触发一次GC进行内存回收。
paused 2ms 2ms表明GC暂停的时间。从这里你可以看到越大的heap size你需要暂停的时间越长。如果是concurrent gc你会看到2个时间一个开始一个结束,这时间是很短的,但如果是其他类型的GC,你很可能只会看到一个时间,而这个时间是相对比较长的。

### Android 垃圾回收机制及其优化 #### 什么是垃圾回收? 垃圾回收(Garbage Collection, GC)是一种自动内存管理技术,用于释放不再使用的对象所占用的内存资源。在 Android 中,Java 虚拟机(JVM 或 ART - Android Runtime)负责执行此操作。 当基于垃圾收集器的选择时,已回收的内存区域可能会被即时压缩或者通过单独的一次遍历完成[^1]。这种行为取决于具体的垃圾收集算法以及其配置方式。 #### Android垃圾回收实现 Android 使用的是 ART 运行环境来替代之前的 Dalvik VM。ART 提供了几种不同的垃圾回收策略以适应应用的不同需求: - **分代回收**:类似于 JVM 的概念,分为年轻代(Generation 0)、老年代等层次结构。如果某些数据能够从较年轻的世代提升到更成熟的世代,则会按照字节每秒的速度进行升级处理[^2]。 - **并发标记清除 (CMS)** 和其他高级算法也被采用,在减少暂停时间的同时提高效率。 #### 如何优化 Android 应用中的 GC 性能? 为了改善应用程序运行期间因频繁触发 GC 导致卡顿等问题,可以采取以下措施之一: 1. 避免创建过多短生命周期的对象; 2. 尽量重用对象而不是不断新建实例; 3. 减少大对象分配频率; 4. 设置合适的参数控制游标的销毁时机从而避免不必要的开销[^4]; 此外还可以利用编译期优化手段去除无用代码片段进一步节省空间并加快启动速度[^3]。 ```java // 示例代码展示如何有效管理Bitmap资源防止OOM错误发生 public void loadBitmap(String path){ try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeFile(path,options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; float scaleFactor = Math.min((float)imageHeight / REQUIRED_HEIGHT,(float)imageWidth /REQUIRED_WIDTH); options.inSampleSize = calculateInSampleSize(options,scaleFactor); options.inJustDecodeBounds=false; return BitmapFactory.decodeFile(path,options); } catch(OutOfMemoryError e){ Log.e(TAG,"Out Of Memory Error while loading bitmap",e); } } private static int calculateInSampleSize(BitmapFactory.Options options,float scale){ ... } ``` 上述例子展示了加载图片过程中合理调整采样率的重要性,这有助于降低内存消耗风险。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值