生活工程体验信仰哲学精神
投稿投诉
精神世界
探索历史
哲学文学
艺术价值
信仰创造
境界审美
体验技术
技能工具
工程信息
医学生产
生活运用
操作能力

Android技术分享Android中部分内存泄漏示例及解决

5月9日 亡命徒投稿
  简单介绍内存泄漏内存抖动
  内存泄漏:Memoryleak,是一种资源泄漏,主因是计算机程序对存储器配置管理失当,失去对一段已分配内存空间的控制,造成程序继续占用已经不再使用的内存空间,或是存储器所存储之对象无法透过执行代码而访问,令内存资源空耗。
  简单来说,内存泄漏是指无法正确回收已经不再使用的内存。
  举例:
  请注意以下的例子是虚构的在此例中的应用程序是一个简单软件的一小部分,用来控制电梯的运作。
  此部分软件当乘客在电梯内按下一楼层的按钮时运行。
  当按下按钮时:
  要求使用存储器,用作记住目的楼层
  把目的楼层的数字储存到存储器中
  电梯是否已到达目的楼层?
  如是,没有任何事需要做:程序完成
  否则:
  等待直至电梯停止
  到达指定楼层
  释放刚才用作记住目的楼层的存储器
  此程序有一处会造成存储器泄漏:如果在电梯所在楼层按下该层的按钮(即上述程序的第4步),程序将触发判断条件而结束运行,但存储器仍一直被占用而没有被释放。这种情况发生得越多,泄漏的存储器也越多。
  这个小错误不会造成即时影响。因为人不会经常在电梯所在楼层按下同一层的按钮。而且在通常情况下,电梯应有足够的存储器以应付上百次、上千次类似的情况。不过,电梯最后仍有可能消耗完所有存储器。这可能需要数个月或是数年,所以在简单的测试下这个问题不会被发现。
  而这个例子导致的后果会是不那么令人愉快。至少,电梯不会再理会前往其他楼层的要求。更严重的是,如果程序需要存储器去开启电梯门,那可能有人被困电梯内,因为电梯没有足够的存储器去开启电梯门。
  存储器泄漏只会在程序运行的时间内持续。例如:关闭电梯的电源时,程序终止运行。当电源再度开启,程序会再次运行而存储器会重置,而这种缓慢的泄漏则会从头开始再次发生。
  内存抖动
  源自Android文档中的Memorychurn一词,中文翻译为内存抖动。
  指快速频繁的创建对象从而产生的性能问题。
  引用Android文档原文:垃圾回收事件通常不会影响应用的性能。不过,如果在短时间内发生许多垃圾回收事件,就可能会快速耗尽帧时间。系统花在垃圾回收上的时间越多,能够花在呈现或流式传输音频等其他任务上的时间就越少。
  通常,内存抖动可能会导致出现大量的垃圾回收事件。实际上,内存抖动可以说明在给定时间内出现的已分配临时对象的数量。
  例如,您可以在for循环中分配多个临时对象。或者,您也可以在视图的onDraw()函数中创建新的Paint或Bitmap对象。在这两种情况下,应用都会快速创建大量对象。这些操作可以快速消耗新生代(younggeneration)区域中的所有可用内存,从而迫使垃圾回收事件发生。
  内存泄漏(Memoryleak)的产生和避免方式
  Java内存泄漏的根本原因是长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄漏。
  尽管短生命周期对象已经不再需要,但因为长生命周期依旧持有它的引用,故不能被回收而导致内存泄漏。
  几种引起内存泄漏的问题:
  静态集合类引起的内存泄漏
  HashMap、ArrayList等集合以静态形式声明时,这些静态对象的生命周期与应用程序一致。他们所引用的对象也无法被释放,因为它们也被集合引用着。privatestaticHashMapString,ObjectanewHashMap();publicstaticvoidmain(Stringargs〔〕){for(inti0;i1000;i){ObjecttOnewObject();a。put(0,tO);tO}}
  如果仅仅释放引用本身(tOnull),ArrayList依然在引用该对象,GC无法回收。
  监听器
  在Java应用中,通常会用到很多监听器,一般通过addXXXXListener()实现。但释放对象时通常会忘记删除监听器,从而增加内存泄漏的风险。
  各种连接
  如数据库连接、网络连接(Socket)和IO连接。忘记显式调用close()方法引起的内存泄漏。
  内部类和外部模块的引用
  内部类的引用是很容易被遗忘的一种,一旦没有释放可能会导致一系列后续对象无法释放。此外还要小心外部模块不经意的引用,内部类是否提供相应的操作去除外部引用。
  单例模式
  由于单例的静态特性,使其生命周期与应用的生命周期一样长,一旦使用不恰当极易造成内存泄漏。如果单利持有外部引用,需要注意提供释放方式,否则当外部对象无法被正常回收时,会进而导致内存泄漏。
  常见的内存泄漏处理方式:
  集合类泄漏
  如集合的使用范围超过逻辑代码的范围,需要格外注意删除机制是否完善可靠。比如由静态属性static指向的集合。
  单利泄漏
  以下为简单逻辑代码,只为举例说明内存泄漏问题,不保证单利模式的可靠性。publicclassAppManager{privatestaticAppMprivateCprivateAppManager(Contextcontext){this。}publicstaticAppManagergetInstance(Contextcontext){if(instancenull){instancenewAppManager(context);}}}
  AppManager创建时需要传入一个Context,这个Context的生命周期长短至关重要。
  1。如果传入的是Application的Context,因为Application的生命周期等同于应用的生命周期,所以没有任何问题。
  2。如果传入的是Activity的Context,则需要考虑这个Activity是否在整个生命周期都不会被回收了,如果不是,则会造成内存泄漏。
  非静态内部类创建静态实例造成的内存泄漏publicclassMyActivityextendsAppCompatActivity{privatestaticMyInnerClassmInnerCOverrideprotectedvoidonCreate(BundlesavedInstanceState){super。onCreate(savedInstanceState);。。。if(mInnerClassnull){mInnerClassnewMyInnerClass();}}classMyInnerClass{。。。}}
  内部类持有外部类引用,而static声明的对象声明周期通常会比Activity长。即使关闭这个页面,由于mInnerClass为静态的,并且持有MyActivity的引用,导致无法回收此页面从而引起内存泄漏。
  应该将该内部类单独封装为一个单例来使用。
  匿名内部类异步线程publicclassMyActivityextendsAppCompatActivity{OverrideprotectedvoidonCreate(BundlesavedInstanceState){super。onCreate(savedInstanceState);。。。newThread(newRunnable(){Overridepublicvoidrun(){。。。}})。start();}}
  Runnable都使用了匿名内部类,将持有MyActivity的引用。如果任务在Activity销毁前未完成,将导致Activity的内存无法被回收,从而造成内存泄漏。
  解决方法:将Runnable独立出来或使用静态内部类,可以避免因持有外部对象导致的内存泄漏。
  Handler造成的内存泄漏publicclassSampleActivityextendsAppCompatActivity{privatefinalHandlermHandlernewHandler(){OverridepublicvoidhandleMessage(Messagemsg){。。。}}OverrideprotectedvoidonCreate(BundlesavedInstanceState){。。。mHandler。postDelayed(newRunnable(){Overridepublicvoidrun(){。。。}},300000);finish();}}
  Handler属于TLS(ThreadLocalStorage)变量,生命周期与Activity是不一致的,容易导致持有的对象无法正确被释放
  当Android应用程序启动时,该应用程序的主线程会自动创建一个Looper对象和与之关联的MessageQueue。
  当主线程中实例化一个Handler对象后,它就会自动与主线程Looper的MessageQueue关联起来。所有发送到MessageQueue的Messag都会持有Handler的引用,所以Looper会据此回调Handle的handleMessage()方法来处理消息。只要MessageQueue中有未处理的Message,Looper就会不断的从中取出并交给Handler处理。
  另外,主线程的Looper对象会伴随该应用程序的整个生命周期。
  在Java中,非静态内部类和匿名类内部类都会潜在持有它们所属的外部类的引用,但是静态内部类却不会。
  当该Activity被finish()掉时,延迟执行任务的Message还会继续存在于主线程中,它持有该Activity的Handler引用,所以此时finish()掉的Activity就不会被回收了从而造成内存泄漏(因Handler为非静态内部类,它会持有外部类的引用,在这里就是指SampleActivity)。
  解决方法:在Activity中避免使用非静态内部类,比如上面我们将Handler声明为静态的,则其存活期跟Activity的生命周期就无关了。同时通过弱引用的方式引入Activity,避免直接将Activity作为context传进去,见如下代码:publicclassSampleActivityextendsAppCompatActivity{privatestaticclassMyHandlerextendsHandler{privatefinalWeakReferenceSampleActivitymApublicMyHandler(SampleActivityactivity){mActivitynewWeakReferenceSampleActivity(activity);}OverridepublicvoidhandleMessage(Messagemsg){SampleActivityactivitymActivity。get();if(activity!null){。。。}}}privatefinalMyHandlermHandlernewMyHandler(this);privatestaticfinalRunnablemRunnablenewRunnable(){Overridepublicvoidrun(){。。。}}OverrideprotectedvoidonCreate(BundlesavedInstanceState){。。。mHandler。postDelayed(mRunnable,300000);finish();}}
  避免不必要的静态成员变量
  对于BroadcastReceiver、ContentObserver、File、Cursor、Stream、Bitmap等资源的使用,应在Activity销毁前及时关闭或注销。
  不使用WebView对象时,应调用destroy()方法销毁。
投诉 评论 转载

Android技术分享Android中部分内存泄漏示例及解决简单介绍内存泄漏内存抖动内存泄漏:Memoryleak,是一种资源泄漏,主因是计算机程序对存储器配置管理失当,失去对一段已分配内存空间的控制,造成程序继续占用已经不再使用……女生想要脸上干净不长痘,坚持这4个好习惯,皮肤会越来越好对于女生来说,除了身材,最重要的就是脸了,一张漂亮的脸,能给你带来好运和自信,并且还能收获爱情,而无论是怎样的美貌,都离不开干净的肌肤状态,毕竟干净的肌肤,才能带给人气质和亲切……赵丽颖带儿子逛商场,母子互动超有爱,晚上一起回冯绍峰家说起赵丽颖和冯绍峰这一对,很多人都觉得有点可惜,毕竟两人在一起时那么甜蜜,2018年10月,两人官宣结婚,2019年3月,就迎来了他们的爱情结晶。原本以为,一家三口会幸福……孩子正长身体?多吃4种美食,个头蹭蹭涨,一上桌就抢光孩子吃饭总是个问题,要不是不爱吃饭,要不就是不爱吃蔬菜,总之没有老老实实的吃饭时候,尤其是现在是春天,可以说是孩子长个子的黄金期,这时候营养到了,孩子还愁不长个,今天教你4种美……我眼中的华山虽不敢自称名川大山的爱好者,却也爱山爱水。一次偶然的机会到了陕西,借机登了华山。崔巍的华山,让我感觉自己的渺小和可怜,只能惊叹于大自然的鬼斧神工,居然能弄出那么震撼人心的……为何明十三陵对外开放的景区很少,清朝皇陵却几乎全部对外开放?明朝和清朝作为中国历史上最后的两个封建王朝,这两个王朝的皇陵也成为了现代的热门旅游景点,但是如果去过清东陵和清西陵以及明十三陵的人都会发现那就清东陵和清西陵景区开放很多,而明十……10个假装在境外的宝藏打卡地推荐,不出国门环游世界中国地大物博,好去处实在是太多了,总有一些你不知道的隐藏玩法等你去发现。一、假装在瑞士布里恩茨海坨山谷海坨山谷位于张家口赤城县闫家坪村,紧邻北京延庆区,本是一个默默……属于年轻小夫妻的丰田床车,2。0T6AT城市也能开,通勤旅游Hello,大家好日常我们给大家介绍的丰田海狮床车,外观都比较普通,内部也鲜有新颖的设计,不过今天要给大家介绍一款不仅外观涂装很帅,内部也采用了不一样设计的丰田海狮露营车……马牙雪山下的滑雪场!玩雪赏景一绝乌鞘岭国际滑雪场。新甘肃每日甘肃网记者李杨邹明敏王昱钧随着北京冬奥会、冬残奥会临近,冰雪运动的氛围日益浓厚,越来越多的群众参与到冰雪运动中,冰雪运动也真正融入了人们……发现违背元素周期表的物质意味着什么?0质量电子又意味着什么?1869年俄罗斯化学家德米特里伊万诺维奇门捷列夫()总结并发表了最初的化学元素周期表。自那时起,人们又陆续发现了诸多新元素;并且还按照元素周期表的规律,人工创造出许多短寿命元素……向鹏输球,主教练崔庆磊直接离场,球迷很不满哈喽大家好欢迎收看刘胖子说球今天是北京时间3月14号!目前的WTT新加坡大满贯比赛已经过去三轮了。而也就在前天的男单比赛中,国乒遭受了重大打击,两名球员出现了严重的爆冷输……诺手自制技能名火了,官方再次和谐名字,鳄鱼被针对的有点惨前言:S11赛季的比赛已经全部结束了,相信绝大多数的玩家都关注了最近一段时间的转会期,各大战队都在陆续官宣自己的新阵容,同时,官方也在准备着新赛季的更新。就在最近,国服的客户端……
调教到位!OPPO多款产品上榜安兔兔性能榜单,ColorOS之远造句用之远造句大全提供多种潮流配色供选,几何E售8。68一线车讯夏日炎炎注意身体井柏然刘雯酒店被拍,优秀的人就应该在一起,如果是真的那就祝福如何提高销售业绩别墅庄园!文华东方推出私享奢居系列台积电先进工艺太贵,苹果A16成本翻倍,iPhone快用不起华为跌倒,苹果吃饱名将秦琼是怎么变成门神的秦琼为什么是门神老年人吃油太多危害健康棉花施用甲哌鎓需要注意什么小米mix4怎么调出键盘声音揭秘石达开之死石达开死在了哪里老年痴呆的奶奶构成污染环境罪特别严重的后果是什么关于汽车轮胎的安全常识您了解多少一试就灵!慢性咽炎总不好?中医有方法!自我调护学起来!遗产继承需要准备什么材料核桃仁做粥应该怎么做惠英红我就是演员总决赛受邀担任决战参谋官现场即兴表演一秒入戏苹果手机微信怎么查定位(苹果手机位置在哪里)晒宠物朋友圈jm黄金蚕丝面膜要洗嘛jm黄金蚕丝面膜使用方法

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找