cf游戏内闪退(cf莫名闪退)

2023-12-18 10:37 星期一 48点热度 0人点赞 0条评论

cf游戏内闪退(cf莫名闪退)插图

对于众多 Android 程序员而言,在需求与应用性能之间,主要精力都会聚焦新需求的开发。随着项目复杂度的增加,应用性能越来越低,各类故障频发。程序员们奔波于各种“救火现场”,疲于奔命。本文将根据笔者在 Android 应用程序开发过程中所遇以及思考,针对内存泄漏提炼出一套可以应用于开发中的基础篇方法论,也许会让你的开发效率事半功倍。

先从管理好内存应用开始

提及Random-access memory(随机存取存储器RAM)大家并不陌生,在任何软件开发环境中它都是宝贵的资源,而对于物理内存经常受到限制的移动操作系统来说,它就更具价值了。尽管Android Runtime(ART)和Dalvik虚拟机都会执行常规的垃圾收集(GC),但这并不意味着你可以忽略你的应用分配和释放内存的时间和位置,此时你仍然需要避免引入内存泄漏。

什么是内存溢出和内存泄漏?

内存溢出(Out Of Memory Error):为了允许多进程,Android为每个应用程序分配的堆大小设置了硬性限制。确切的堆大小限制,会根据设备有多少内存总量而有所不同。如果你的应用程序使用的内存已达到该限制并尝试分配更多内存时,系统就会抛出内存溢出;

内存泄漏(Memory Leak):是指应用在申请内存后,无法释放已申请的内存空间,是对内存资源的浪费。最坏的情况下,内存泄漏会最终导致内存溢出。

明确内存泄漏的危害性

一次内存泄漏的危害及影响并不大,但也不能放任不管。最坏的情况下,可能导致你的 APP 由于大量的内存泄漏而将内存耗尽,进而出现闪退状况,但这并非是常态。相反,内存泄漏会消耗大量的APP内存,但却不至于内存耗尽,这时,APP 会由于内存不够分配而频繁触发GC。而GC是非常耗时的操作,会导致严重的卡顿。另外,当你的应用处于LRU列表中(即切换到后台,变为后台进程)时,由于内存泄漏而消耗了更多内存,当系统资源不足而需要回收一部分缓存进程时,你的应用被系统杀死的可能性就更大了。

Tips:

为什么我们在平时开发中并不太在意的GC会导致卡顿?你需要了解GC相关知识,包括“Full GC / Minor GC”、“GC停顿”等;

应用进程在整个LRU列表中消耗的内存越少,保留在列表中并且能够快速恢复的机会就越大。

常用内存泄漏检测工具——LeakCanary

LeakCanary是大家所熟知的内存泄漏检测工具,它简单易用,集成以后能在应用发生泄漏时发出警告,并显示发生泄漏的堆栈信息,新版本还会显示具体泄漏的内存大小,作为被动监控泄漏的工具非常有效,但LeakCanary功能有限,不能提供更详细的内存快照数据,并且需要嵌入到工程中,会在一定程度上污染代码,所以一般都只在build version中集成,release version中则应该去掉。

借助内存分析工具——MAT

MAT(Memory Analyzer Tool)是基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看什么阻止了垃圾收集器的回收工作,并通过报表直观的查看到可能造成这种结果的对象。

除了Eclipse插件版,MAT也有独立的不依赖Eclipse的版本,只不过这个版本在调试Android内存的时候,需要将DDMS生成的文件进行转换,才可以在独立版本的MAT上打开。因为DDMS生成的是Android格式的HPROF(堆转储)文件,而MAT只能识别JAVA格式的HPROF文件。不过Android SDK中已经提供了这个Tools,所以使用起来也是很方便的。

要调试内存,首先需要获取HPROF文件,HPROF文件存储的是特定时间点,java进程的内存快照。有不同的格式来存储这些数据,总的来说包含了快照被触发时java对象和类在heap中的情况。由于快照只是一瞬间的事情,所以heap dump中无法包含一个对象在何时、何地(哪个方法中)被分配这样的信息。出于篇幅考虑,此处不再讲解MAT的使用,有兴趣的读者可以参考官方文档。

如何避免写出内存泄漏的代码

谨慎使用static关键字,切勿使用static修饰Activity context;

注意不要让类变量直接或间接地持有Activity context引用;

尽量不要在单例中使用Activity context,如果要用,不能将其作为全局变量;

时刻注意内部类(尤其是Activity的内部类)的生命周期,尽量使用静态内部类代替内部类,如果内部类需要访问外部类的成员,可以用“静态内部类+弱引用”代替;内部类的生命周期不应该超出外部类,外部类结束前,应该及时结束内部类生命周期(停止线程、AsyncTask、TimerTask、Handler消息等,移除类变量或长生命周期的线程对Callback、listener等的强引用);

及时注销广播以及一些系统服务的监听器;

属性动画在Activity销毁前记得cancel;

文件流、Cursor等资源用完及时关闭;

Activity销毁前WebView的移除和销毁;

使用别人的方法(尤其是第三方库),遇到需要传递context时尽量使用ApplicationContext,而不要轻易使用Activity context,因为你不知道别人的代码内部会不会造成该context的泄漏。比如微信支付SDK历史版本中就曾出现过内存泄漏的问题,微信支付初始化时需要传入context,最终由WXApiImpl这个类持有了context,如果你传入的是activity context,就会被WXApiImpl泄漏。

重点知识点梳理

GC如何判断某个对象是否可以被回收:在垃圾回收过程中,当一个对象到GC Roots 没有任何引用链(或者说,从GC Roots 到这个对象不可达)时,垃圾回收器就会释放掉它;

Java的引用级别:强引用 – 软引用 – 弱引用 – 虚引用;

JVM宁可抛出OOM也不会去回收一个有强引用的对象;

GC Root:有多种方法使得一个对象成为GC Root,GC Root是由虚拟机自身保持存活的对象,所以它不会被回收,由GC Root强引用的对象也无法被回收;

内部类和静态内部类:内部类的一大优势就是可以直接引用外部类的成员,这是通过隐式地持有外部类的引用来实现的;而静态内部类,由于不再隐式地持有外部类的引用,也就无法直接引用外部类的成员了;

如何避免内部类造成的泄漏:为避免内部类泄漏外部类,应该使用静态内部类。但静态内部类又无法访问外部类的成员,为解决该问题,可以使用“静态内部类+弱引用”,让静态内部类持有外部类的弱引用,既不会造成泄漏,又能解决访问外部类的成员变量的问题;

LeakCanary如何检查是否存在内存泄漏:WeakReference + ReferenceQueue。

希望通过今天这篇文章,能够让开发者了解到什么是内存泄漏及内存泄漏给带来的影响,同时希望大家通过文内步骤依次检测及修复内存泄漏问题,从现在开始,构建高质量/高性能的应用。处理内存泄漏不仅能让你的应用有更好的用户体验,也能让你成为更好的开发者,让我们朝着这个目标努力吧!

PS:后期,公众号将推出《针对Android 内存泄漏,如何做一个有“洁癖”的开发者(实战篇)》记得届时来关注。

-END-

参考文献

[Eight Ways Your Android App Can Leak Memory](http://blog.nimbledroid.com/2016/05/23/memory-leaks.html)

[Android内存优化——常见内存泄漏及优化方案](https://www.jianshu.com/p/ab4a7e353076)

[LeakCanary on GitHub](https://github.com/square/leakcanary)

[用LeakCanary检测内存泄漏](https://academy.realm.io/cn/posts/droidcon-ricau-memory-leaks-leakcanary/)

[Overview of memory management](https://developer.android.com/topic/performance/memory-overview)

[Video:Memory management on Android Apps](https://www.youtube.com/watch?v=_CruQY55HOk)

相关推荐

本胖狐今天带来两款全新的CF道具透明头盔、透明护目镜!赶快追随灵狐姐的步伐吧!(体验服内容不代表最终结果,如后续有所变动当以正服内容为准!) 仓库展示 如图为透明头盔和透明护目镜的仓库展示图,从图中我…

最近有很多朋友在玩游戏的时候,发现会有虚拟光驱程序冲突的问题,比如说安装游戏模拟人生2后,系统提示虚拟光驱程序冲突。 1、 打开虚拟光驱DAEMON,在装载镜像的界面,点击“参数选择”,如下图 2、 …

华为手机开机密码总开如何重置? 大家好,今天带来了一台华为的MATE40PRO,这个机器就是现在屏幕有密码锁已经忘掉了,这种情况应该怎么样去重新找回密码,或者怎么样来把密码解除? ·首先要去按关机键,…

玩DNF的玩家都知道,安全模式一般出现在异地登录的情况较多,这是官方为了玩家的利益出现的一种保护模式。防止盗号的情况发生。虽然并不能起到至关重要的作用(该盗还是被盗)。但是初衷还是好的。通常我们用微信…

中文状态下shift+4打出¥ 英文状态下shift+4打出$ shift+5打出% shift+1打出! shift+2打出@ shift+3打出# 中文状态下shift+6打出…… 英文状态下sh…

手机圈里一直流传着一个梗——苹果手机加联通卡等于失联。这个梗虽然也有夸张的成分,但在过去,“苹果+联通”组合的信号表现也确实不尽人意。那么问题来了,马上都要2023年了,5G通信技术早已发生了翻天覆地…

工作中,用好快捷键,可以提升工作效率,告别加班,除了CTRL+C复制,CTRL+V粘贴,CTRL+X剪切以外,我们还要学习20个相关小技巧,看看你会几个?

虽然说NFC功能早在2003年就诞生了,但是到目前为止,NFC的使用范围,还并没有像当初设计者想象的那样发展。 NFC固然有其巨大的优势,比如平时我们用来刷公交、刷地铁、刷门禁,甚至用来绑定银行卡用来…

NTFS与FAT32是两种不同的磁盘文件系统格式,就像两个不同的图书馆,他们书架的摆放,尺寸各不相同,管理方式也各不相同!今天小编就带大家具体了解他们之间差异。 1、磁盘分区容量区别 NTFS可以支持…

什么是dc插座 dc插座是一种与电脑显示器专用电源相配的插座,它是由横向插口、纵向插口、绝缘基座、叉型接触弹片、定向键槽组成,两只叉型接触弹片定位在基座中心部位,成纵横向排列互不相连。叉型接触弹片一端…

2023年了,windows11有必要升级吗?随着windows11系统版本的不断更新,越来越多的用户也开始使用win11系统了。那么经过这么多代更新以后的win11值得升级吗?如果要升级到windo…

大家好,我是鼓鼓硕0721,今天带来以下文章 五笔打字:曾经风光无限,如今逐渐被拼音取代?五笔打字,一提起就让人望而却步。背字根,对于很多人来说,似乎太难了,背不来。我自己使用五笔输入法,对于字根的位…

QQ聊天记录包括很多种形式的文件,比如图片、视频、音频、文档等等,是我们与朋友、家人、同事之间的重要记录。有时候我们可能无法直接在QQ里查看到所需聊天记录,那么这时候就需要知道qq聊天记录文件夹的位置…

倍受期待的CF三月全新版本终于在不久前更新完成了,有很多CFer现在依旧被困在家里无法出门,这个时候更新CF,第一时间体验新玩法绝对是再合适不过的选择了。而在全新版本中刀战占领玩法就吸引了不少玩家的关…

对于复杂的PCB布局布线设计之前,最重要的工作是做好规则(rule)制定,这样才能在PCB布线过程中时刻确保设计的规范是满足自己要求,而不会说在完成设计再检查后才发现一堆错误问题,或者要修改时,会要牵…

在vivo的开发者大会上,蓝河操作系统blueOS的亮相无疑给人们带来了极大的惊喜。vivo作为一个知名的智能手机制造商,其自主研发的操作系统将为其在未来的市场竞争中带来更多的话语权和主动权。 viv…

近几年,随着短视频火遍大江南北,很多人都喜欢采用自己拍摄或制作视频的方式,记录和分享生活。 但合适的背景音乐并不那么容易,有时候找到了但人声太重不适合,这时候就需要将人声和背景音乐分离。 分离人声和背…

最初的计算机由于价格昂贵,因此,一台计算机一般是由多个人同时使用的。每个操作者会有一个这样专门的设备:它只有显示器和键盘,还有简单的处理电路,本身不具有处理计算机信息的能力。这个专门的设备,通常是通过…

视频播放不了怎么办?众所周知,视频格式有很多种,比如 AVI格式、NAVI格式、ASF格式MOV格式 、WMV格式、FLV/F4V格式、H.264、H.265等等,其实它们之间都可以进行相互转换。但在…

听音乐或电影的时候,如果总会出现“噼噼啪啪”的声音,或者无论如何都调不出声音,该怎么办?还在靠“重启大法”解决音量问题?是时候考虑直治根本的解决方案了!本期内容,将为大家介绍电脑爆音、杂音、没有声音的…