`
bogongjie
  • 浏览: 235455 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

android垃圾回收机制及程序优化System.gc

阅读更多

1.垃圾收集算法的核心思想

  Java语言建立了垃圾收集机制,用以跟踪正在使用的对象和发现并回收不再使用(引用)的对象。该机制可以有效防范动态内存分配中可能发生的两个危险:因内存垃圾过多而引发的内存耗尽,以及不恰当的内存释放所造成的内存非法引用。

  垃圾收集算法的核心思想是:对虚拟机可用内存空间,即堆空间中的对象进行识别,如果对象正在被引用,那么称其为存活对象,反之,如果对象不再被引用,则为垃圾对象,可以回收其占据的空间,用于再分配。垃圾收集算法的选择和垃圾收集系统参数的合理调节直接影响着系统性能,因此需要开发人员做比较深入的了解。

2.触发主GC(Garbage Collector)的条件

  JVM进行次GC的频率很高,但因为这种GC占用时间极短,所以对系统产生的影响不大。更值得关注的是主GC的触发条件,因为它对系统影响很明显。总的来说,有两个条件会触发主GC:

  ①当应用程序空闲时,即没有应用线程在运行时,GC会被调用。因为GC在优先级最低的线程中进行,所以当应用忙时,GC线程就不会被调用,但以下条件除外。

  ②Java堆内存不足时,GC会被调用。当应用线程在运行,并在运行过程中创建新对象,若这时内存空间不足,JVM就会强制地调用GC线程,以便回收内存用于新的分配。若GC一次之后仍不能满足内存分配的要求,JVM会再进行两次GC作进一步的尝试,若仍无法满足要求,则 JVM将报“out of memory”的错误,Java应用将停止。

  由于是否进行主GC由JVM根据系统环境决定,而系统环境在不断的变化当中,所以主GC的运行具有不确定性,无法预计它何时必然出现,但可以确定的是对一个长期运行的应用来说,其主GC是反复进行的。

3.减少GC开销的措施

  根据上述GC的机制,程序的运行会直接影响系统环境的变化,从而影响GC的触发。若不针对GC的特点进行设计和编码,就会出现内存驻留等一系列负面影响。为了避免这些影响,基本的原则就是尽可能地减少垃圾和减少GC过程中的开销。具体措施包括以下几个方面:

  (1)不要显式调用System.gc()

  此函数建议JVM进行主GC,虽然只是建议而非一定,但很多情况下它会触发主GC,从而增加主GC的频率,也即增加了间歇性停顿的次数。

  (2)尽量减少临时对象的使用

  临时对象在跳出函数调用后,会成为垃圾,少用临时变量就相当于减少了垃圾的产生,从而延长了出现上述第二个触发条件出现的时间,减少了主GC的机会。

  (3)对象不用时最好显式置为Null

  一般而言,为Null的对象都会被作为垃圾处理,所以将不用的对象显式地设为Null,有利于GC收集器判定垃圾,从而提高了GC的效率。

  (4)尽量使用StringBuffer,而不用String来累加字符串(详见blog另一篇文章JAVA中String与StringBuffer)

  由于String是固定长的字符串对象,累加String对象时,并非在一个String对象中扩增,而是重新创建新的String对象,如 Str5=Str1+Str2+Str3+Str4,这条语句执行过程中会产生多个垃圾对象,因为对次作“+”操作时都必须创建新的String对象,但这些过渡对象对系统来说是没有实际意义的,只会增加更多的垃圾。避免这种情况可以改用StringBuffer来累加字符串,因StringBuffer 是可变长的,它在原有基础上进行扩增,不会产生中间对象。

  (5)能用基本类型如Int,Long,就不用Integer,Long对象

  基本类型变量占用的内存资源比相应对象占用的少得多,如果没有必要,最好使用基本变量。

  (6)尽量少用静态对象变量

  静态变量属于全局变量,不会被GC回收,它们会一直占用内存。

  (7)分散对象创建或删除的时间

  集中在短时间内大量创建新对象,特别是大对象,会导致突然需要大量内存,JVM在面临这种情况时,只能进行主GC,以回收内存或整合内存碎片, 从而增加主GC的频率。集中删除对象,道理也是一样的。它使得突然出现了大量的垃圾对象,空闲空间必然减少,从而大大增加了下一次创建新对象时强制主GC 的机会。

 

-------------------------------------------------------------

很多人把Java的“效率低下”归咎于不能自由管理内存,但我们也知道将内存管理封装起来的好处,这里就不赘述。

Java中的内存分配是随着new一个新的对象来实现的,这个很简单,而且也还是有一些可以“改进”内存回收的机制的,其中最显眼的就是这个System.gc()函数。

乍一看这个函数似乎是可以进行垃圾回收的,可事实并不是那么简单。
其实这个gc()函数的作用只是提醒虚拟机:程序员希望进行一次垃圾回收。但是它不能保证垃圾回收一定会进行,而且具体什么时候进行是取决于具体的虚拟机的,不同的虚拟机有不同的对策。

那么下一个问题就是:gc()进行回收的准则是什么?也就是说什么样的对象可以被回收?
简单来说就是:没有被任何可达变量指向的对象。这里的可达是我发明的……意思就是能够找到的,那什么样的是不可达的呢?
比如说:
a.v = b;
b.v = c;
/*
 *Watch out !
 */
a.v = d;
看一下这段代码:
第一行:对象a的变量v指向了对象b
第二行:对象b的变量v指向了对象c
第六行:对象a的变量v指向了变量d。
这个时候,虽然变量c指向的对象有c 以及b.v指向它,但是它们都已经不可达了,为什么?因为唯一可以找到它们的是a.v,但是现在a.v指向了d,所以他们就是不可达的了。

理由也很直观:没有任何可达变量指向你,你还有活下去的理由吗?你就算活下去谁能找得到你呢?

所以说,C++中将释放了的指针置为null的习惯要保留到Java中,因为这有可能是你释放内存的唯一途径。

最后的箴言:不要频繁使用gc函数。

 

转载: http://blog.vunso.com/201307/android%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E6%9C%BA%E5%88%B6%E5%8F%8A%E7%A8%8B%E5%BA%8F%E4%BC%98%E5%8C%96system-gc.htm

分享到:
评论

相关推荐

    Android垃圾回收机制及程序优化System.gc

    在Android开发中,理解垃圾回收(Garbage Collection, GC)机制和如何进行程序优化至关重要,因为这直接影响到应用的性能和用户体验。Java语言内置的垃圾回收机制是自动管理内存的关键特性,它负责清理不再使用的...

    Android中高级面试必知必会.pdf

    垃圾回收算法(JVM)..........63 7、垃圾回收机制和调用 System.gc()的区别? .64 8. 类加载过程90 9. 反射..........101 10. 多线程和线程池........112 11.HTTP、HTTPS、TCP/IP、Socket 通信、三次握手四次挥手...

    Dalvik虚拟机垃圾收集(GC)过程分析.docx

    垃圾收集(Garbage Collection, GC)是一项自动化管理内存的技术,它自动识别并回收那些不再被程序使用的对象所占用的内存空间。这对于提高程序运行效率及减少内存泄漏等问题具有重要意义。对于Android平台而言,其...

    android audio system

    标题和描述均提到了“Android音频系统”,这指向了Android平台上的音频管理和服务。...在开发或调试涉及音频的应用时,仔细检查音频设备的识别和配置,以及合理利用垃圾回收机制,都是保持应用稳定性和性能的关键因素。

    android 知识汇总

    在Android开发中,掌握以下几个核心知识点至关重要:Activity、Service、Thread、AsyncTask以及系统垃圾回收(system.gc)。这些是Android应用程序中的基础元素,理解和熟练运用它们对于构建高效、稳定的App至关重要...

    android内存管理

    Android系统基于Java虚拟机(JVM),它自带了垃圾收集(Garbage Collection, GC)机制,用于自动回收不再使用的内存,避免内存泄漏。然而,尽管有了GC,开发者仍然需要对内存使用进行谨慎的规划和优化。 1. **手动...

    android开发笔试题及答案

    在Java内存管理问题上,内存回收(Garbage Collection)是由Java虚拟机(JVM)自动管理的,开发者不需要手动创建线程来释放内存,JVM会定期进行内存回收,但开发者可以通过System.gc()方法建议JVM进行垃圾回收。...

    Android防止内存溢出浅析.zip

    - **垃圾回收(GC)**:Android系统有自动垃圾回收机制,用于回收不再使用的对象,释放内存。 2. **内存溢出原因** - **大对象**:占用大量内存的大对象可能导致内存不足,例如大尺寸的位图图像。 - **内存泄漏*...

    内存优化-android

    使用`System.gc()`虽然可以触发垃圾回收,但不应频繁使用,因为它可能会打断用户体验。更好的做法是让系统自动管理内存,通过引用计数和可达性分析来确定何时回收对象。 源代码优化也是内存管理的重要部分。开发者...

    Android手机管家源码.rar

    源码中可能包含内存分析模块,通过Java层的Runtime类获取系统内存信息,然后调用System.gc()触发垃圾回收,或者使用ActivityManagerNative接口释放进程缓存。此外,可能会有自定义的内存优化算法,如优先级排序和...

    http://elinux.org/Android_Memory_Usage

    2. **内存分配与释放**:Java对象在Dalvik/ART堆上的分配,以及如何通过`System.gc()`和自动垃圾回收机制进行释放。 3. **内存泄漏**:什么是内存泄漏,如何通过分析工具检测内存泄漏,以及如何避免它们,包括避免...

    Android性能调优之内存泄露1

    在Android系统中,垃圾回收机制是沿着GC Root不断回收的,能被访问到的都是不会被回收的。系统每进行一次GC操作时,都会在LogCat中打印一条日志,我们只要去分析这条日志就可以了。 GC日志的基本格式如下所示: D/...

    大量图片优化

    - 使用完Bitmap后,记得调用`recycle()`方法回收内存,并通过`System.gc()`提示系统进行垃圾回收。但需要注意,`System.gc()`只是建议执行垃圾回收,不保证立即执行,且过度使用会影响性能。 6. **避免一次性加载...

    基于Android防止内存溢出浅析

    虽然通常不应直接调用System.gc(),但在特定情况下,如大量对象不再使用且手动清理困难时,可考虑使用System.runFinalization()和System.gc()配合使用,以触发垃圾回收。 总结来说,防止Android应用出现内存溢出,...

    Android面试题大全(中高级)

    面试题还包括了垃圾回收机制与System.gc()调用的区别,类加载过程,反射机制,多线程和线程池的使用,设计模式,以及Java中的四大引用和泛型等。这些都是Java开发者必须掌握的知识点。 第四章Android面试题部分,...

    Android内存泄漏[参考].pdf

    - 不确定性:尽管Java提供了`System.gc()`来触发垃圾回收,但具体何时执行、如何执行取决于JVM实现和配置。通常,GC线程优先级较低,不影响主要应用的执行。 3. 内存泄漏定义 - 内存泄漏:即使对象不再被程序使用...

    Android面试题.

    6. **ListView与内存管理**:面试中可能会讨论如何节约内存,如使用弱引用避免内存泄漏,合理使用Bitmap的配置以减小内存占用,以及何时调用System.gc()或Activity的finish()方法进行内存回收。 7. **Intent的作用*...

Global site tag (gtag.js) - Google Analytics