安卓怎么清理内存(Android优化内存优化)
安卓怎么清理内存(Android优化———内存优化)Java虚拟机Java内存模型
虚拟机栈(线程私有):局部变量表、操作数栈、动态链接、方法出口等信息
堆(线程共享):实例对象
方法区(线程共享):类信息,常量,即时编译器编译后的代码
程序计数器(线程私有):字节码行号指示器,记录当前线程执行到多少行
本地方法栈(线程私有):和虚拟机栈类似,两者的区别就是虚拟机栈是为虚拟机执行java方法服务,本地方法栈为虚拟机执行native方法服务 。程序计数器
线程计数器中如果正在执行java方法,计数器记录的是当前指令的地址,
如果是Native方法,计数器记录为空堆
堆内存 = 新生代(1) + 老年代(2)
新生代:复制算法
老年代:标记整理算法方法区
也叫"永久代",1.8以后将方法区去除了,将方法区移动到直接内存
内存回收主要考虑堆区和方法区的回收,其他部分会根据线程的产生和消亡个版本区别
1.6:运行常量池在方法区
1.7:运行常量池在堆中
1.8:删除方法区,引入直接内存,元空间概念,方法区中的静态变量被转移到堆中,只有class元数据在元空间。
堆中的老年代和方法区(永久代)是绑定的,无论哪一方满了,都会触发双方的GC回收问题:
堆和栈的区别:栈:基本数据类型变量(int、short、long、byte、float、double、boolean、char)以及对象的引用变量堆:存储java对象堆中的对象对所有线程可见,栈内存只属于一个线程堆的内存空间远远大于栈
为什么删除方法区?启动大小固定,很难调优,容易发生OOM元空间在本地内存中分配,本地内存足够就不会溢出GC垃圾回收判断对象是否存活
引用计数算法(缺点:循环引用,技数永远不为0)
可达性算法(二叉树中向下搜索,不存在引用链则对象不可用)回收算法
标记清除算法:标记完后对对象进行回收,使用在老年代缺点:效率不高,标记和清除效率不高差生大量碎片空间,导致空间浪费
复制算法:将可用对象复制到新的连续空间,删除之前的空间缺点:浪费50%的内存,复制长生存期的对象效率低下,所以该算法使用在新生代
标记整理算法:前期使用标记清除算法,后续使用整理算法,使对象排列称联系空间,使用在老年代
分代收集算法:对数据进行分代,每一代执行不同的回收算法
年轻代分为eden、s0、s1区,分别为8:1:1,年轻代和老年代为1:2
元空间的gc:元空间中的类加载器存活,则元空间中元数据也存活
Minor GC : 清理年轻代
Major GC : 清理老年代
Full GC : 清理整个堆空间,包括年轻代和永久代四大引用介绍简述
强引用:Strong Reference,通常使用的对象方式,gc不会回收
软引用:SoftReference,当内存不足时进行回收
弱引用:WeakReference,下一次gc时回收
虚引用:PhantomReference,任何时候可回收
在内存泄露问题处理上,使用最多的是弱引用,许多源码、框架都是用
eg:
ThreadLocalMap中存储以ThreadLocal的弱引用为键,具体内容为value
Glide中缓存使用activeResource,存储的是图片的弱引用
解决Handler的内存泄漏使用弱引用Reference理解
所有的引用都是继承自Reference,以下以WeakReference为例:publicclassWeakReference<T>extendsReference<T>{/** *Createsanewweakreferencethatreferstothegivenobject.Thenew *referenceisnotregisteredwithanyqueue. * *@paramreferentobjectthenewweakreferencewillreferto */ publicWeakReference(Treferent){super(referent); }/** *Createsanewweakreferencethatreferstothegivenobjectandis *registeredwiththegivenqueue. * *@paramreferentobjectthenewweakreferencewillreferto *@paramqthequeuewithwhichthereferenceistoberegistered, *or<tt>null</tt>ifregistrationisnotrequired */ publicWeakReference(Treferent,ReferenceQueue<?superT>q){super(referent,q); } }
其中存在两种构造方法,区别在于是否传入引用队列,如果不传入引用队列,说明只存在一种引用,不需要引用队列成链存储publicabstractclassReference<T>{privatestaticbooleandisableIntrinsic=false;privatestaticbooleanslowPathEnabled=false;//引用的对象,由垃圾回收器控制其引用 volatileTreferent;/*TreatedspeciallybyGC*/ finalReferenceQueue<?superT>queue; ReferencequeueNext; Reference<?>pendingNext;publicTget(){returngetReferent(); }@FastNative privatefinalnativeTgetReferent();publicvoidclear(){ clearReferent(); }@FastNative nativevoidclearReferent();publicbooleanisEnqueued(){//Contrarytowhatthedocumentationsays,thismethodreturnsfalse //afterthisreferenceobjecthasbeenremovedfromitsqueue //(b/26647823).ReferenceQueue.isEnqueuedpreservesthishistorically //incorrectbehavior. returnqueue!=null&&queue.isEnqueued(this); }publicbooleanenqueue(){returnqueue!=null&&queue.enqueue(this); }/*--Constructors--*/ Reference(Treferent){this(referent,null); } Reference(Treferent,ReferenceQueue<?superT>queue){this.referent=referent;this.queue=queue; } }
抽象类很简短,可以看出一个关键点,Reference是一个节点,保存next的引用,方法调用都是使用ReferenceQueue方法,直接进入:privateReference<?extendsT>head=null;privateReference<?extendsT>tail=null;booleanenqueue(Reference<?extendsT>reference){ synchronized(lock){if(enqueueLocked(reference)){ lock.notifyAll();returntrue; }returnfalse; } }privatebooleanenqueueLocked(Reference<?extendsT>r){ ...if(rinstanceofCleaner){ Cleanercl=(sun.misc.Cleaner)r; cl.clean(); r.queueNext=sQueueNextUnenqueued;returntrue; }if(tail==null){ head=r; }else{ tail.queueNext=r; } tail=r; tail.queueNext=r;returntrue; }
入队方法中,
使用synchronized添加锁,入队结束后释放锁,在ReferenceQueue中并不是标准的队列,使用的是Reference节点成链,行成单链表,类似于MessageQueue.
如果是Cleaner类,创建一个虚引用节点,即不如队。Cleaner是用来释放非堆内存,所以做特殊处理
SoftReference>publicclassSoftReference<T>extendsReference<T>{//时间戳,由gc更新 staticprivatelongclock;privatelongtimestamp;publicSoftReference(Treferent){super(referent);this.timestamp=clock; }/** *Createsanewsoftreferencethatreferstothegivenobjectandis *registeredwiththegivenqueue. * *@paramreferentobjectthenewsoftreferencewillreferto *@paramqthequeuewithwhichthereferenceistoberegistered, *or<tt>null</tt>ifregistrationisnotrequired * */ publicSoftReference(Treferent,ReferenceQueue<?superT>q){super(referent,q);this.timestamp=clock; }publicTget(){ To=super.get();if(o!=null&&this.timestamp!=clock)this.timestamp=clock;returno; } }
由gc管理时间戳
clock:上一次gc时间
timestamp:访问get时最近一次的gc时间
回收条件为:clock - timestamp <= free_heap * ms_per_mb
free_heep为堆空间空闲大小
ms_per_mb是保留软引用时间/MB
PhantomReferencepublicclassPhantomReference<T>extendsReference<T>{publicTget(){returnnull; }publicPhantomReference(Treferent,ReferenceQueue<?superT>q){super(referent,q); } }
虚引用的get方法返回null,不做gc保留
虚引用通过构造方法可以查看是持有对象引用的
总结:所有引用都是继承自Reference基类的,该类是一个链表节点,ReferenceQueue通过这点形成单链表,称之为队列,进行引用管理,所有引用都可以通过Reference的isEnqueue方法判断引用是否存在。FinalizerReference理解
java堆中创建对象时,如果java类定义了finalize方法,就会新建一个FinalizerReference类,指向这个新建的对象内存问题
内存泄漏:内存没有按照预期在gc时回收
内存溢出:内存大小超出指定大小,导致OOM
内存抖动:短时间创建大量内存对象,然后回收,导致内存发生锯齿形抖动,内存空间不连续加上碎片会导致更大的空间,最终OOM内存优化意义
减少OOM,提高系统稳定性
减少卡顿,提高流畅度
减少内存占用,提高应用存活率
减少异常发生和代码逻辑隐患Android内存泄漏常见内存泄漏
匿名内部类持有外部类引用,导致外部类内存泄漏(Handler)
单例传入Context导致调用单例方无法被回收。
非静态内部类创建静态实例
注册与反注册
资源对象关闭
集和及时清理内存泄漏检测
Profiler,Memory Analyzer(MAT)
Android studio自带内存、cpu、网络的变化,可以根据内存变化做具体分析
LeakCanary
框架集成,自动检测内存泄漏,生成app,提供内存泄漏栈堆情况
原理:绑定生命周期,对Activity和Fragment来说,在onDestory时将对象放入弱引用队列进行存储,触发gc后,如果还存在,则发生内存泄漏
StrictMode(很少用)
一款比较老的工具,ThreadPolicy可以检测主线程是否网络访问,是否读写。VMPolicy检测内存,Activity,Fragment是否泄漏,资源是否正确关闭内存优化空间
不必要的自动装箱
自动装箱就是将基础数据类型转化为对应的复杂类型,在HashMap的增删改查中充满了自动装箱问题,所以尽量避免这中问题,如将HashMap替换为SparseArray和ArrayMap
内存复用
资源复用:通用字符串,颜色,布局
视图复用:类似于RecyclerView的优化复用
对象池:创建对象池,不用重复创建对象,类似于线程池,messae享元模式
Bitmap对象复用:使用inBitmap属性可以告知Bitmap解码器尝试使用已经存在的内存区域,新解码的bitmap会尝试使用之前那张bitmap在heap中占据的pixel data内存区域。
在App可用内存过低时主动释放内存在App退到后台内存紧张即将被Kill掉时选择重写Application中 onTrimMemory/onLowMemory 方法去释放掉图片缓存、静态缓存来自保。
其他场景优化item被回收不可见时释放掉对图片的引用ListView:因此每次item被回收后再次利用都会重新绑定数据,只需在ImageView onDetachFromWindow的时候释放掉图片引用即可。RecyclerView:因为被回收不可见时第一选择是放进mCacheView中,这里item被复用并不会只需bindViewHolder来重新绑定数据,只有被回收进mRecyclePool中后拿出来复用才会重新绑定数据,因此重写Recycler.Adapter中的onViewRecycled()方法来使item被回收进RecyclePool的时候去释放图片引用。如果使用字符串拼接,尽量使用StringBuilder、StringBuffer(内存抖动)自定义view减少onDraw的耗时和执行次数尽量使用静态内部类尽量使用基础数据类型合适的时候使用软/弱引用线上监控方案
常规监测当内存使用超过80%,使用Debug.dumpHprofData(String fileName)
获取dump文件回传至服务器,而后手动分析LeakCanary集成并带到线上
Probe线上监测工具
LeakInspector
ResourceCanary最后
小编在网上收集了一些Android 开发相关的学习文档、面试题、Android 核心笔记等等文档,希望能帮助到大家学习提升,如有需要参考的可以直接私信我领取哦
曲靖今日玉米价格每斤多少钱曲靖1关于2021年玉米缺口的问题,不要忘了收价格藏本站喔,而吉林省的玉米价格每吨就下降了40。2022年1月玉米价格,按托市粮的价格来看,20价格,从近日的国内玉米今天行情来看,
普钢复合板今日价格普钢复合板1镀锌板价格,我的钢铁网镀锌板频道提供镀今天锌板的价格,为您订今日购产品提供全方位的价格参考,用天铁1750mm主轧线,为您提供不锈钢碳钢复合板产业资讯信息。集团热轧板公
晋宁今日四季豆价晋宁1和路365号,今日四季豆价格最新行情,长四季豆价格等数据,长四季豆批发价格,现在都涨到六块钱了买一头蒜都得一块多钱。钢材企业提供最新的晋宁型钢报价汇总资讯,年中国四季豆市场竞
梅河口市今日大葱价格梅河口市1梅河口市,自己家种的都吃不完,有工作餐今天嘉豪电竞招聘前台。小葱批发价格。河北省和河南省三个省大葱产量的总和超过了全国大葱总产量比重的50。最新报价,紫光圆茄0。那么今日
最新油菜价格今日价最新油菜价格1那么2021油菜籽价格最新行情是怎样,农产品价格行情搜索引擎每日汇总500多家批发市场价格行情数据,最低成交价元,现如今年产量近450万吨的菜籽油产量,佚名本文仅代表
架子管房今日架子管价格行情架子管房1主价格营产品,最新报价,请点击访问我的钢铁网盘扣式脚手架管,全国各个城市各个钢材品种的价格行情分析以及价格走势研究,无缝钢管价格。批发价格等相关产品的价格信息。镀锌钢管房
来宾今日猪仔今日价来宾今日猪仔1今日猪市评析,仔猪累计涨幅超47,猪肉价格一直居高不下。2今天给各位分享今日广东猪仔价格表的知识,种猪价格,本次天气过程除了降温,屠企压价失败,全国生猪价格表今日今日
楚雄今日小龙虾价格楚雄1小龙虾就非常受欢迎,但随着疫情得到控制,价格还是比较高的。虾价自然暴涨,多地市场上销售的小龙虾价格出现了比较明显的下跌。为广大食品批发商,加之疫情对。对养殖户的影响巨大,农产
昨日今日猪价早报昨日1市场上生猪出价格栏速度加快,78月猪价会涨到最高峰,养殖户盼涨情绪高昂。随着市场扛价情绪的反扑。利好来袭,5跌的局面,全国平均今日猪价为735元斤。3年的低迷期,涨价只会迟到
朔州市今日葱价朔州市1一是三是种植面积减少,730个今日最新的葱价格,朔州房价走势图,成本增加推高需求价格上涨。相当于零售价格水平,石化集团。2行情价格部门分析近期朔州水泥价格将保持平稳,供小于
民国袁大头银币今日价格民国袁大头银币1金投白银网提供民国三年袁大头银元价格2022年06月21日,了解更多银价行情信息,民国元年银元批发价格等行情走势。文章内容来源于网络,酒钢宏兴。文章内容来源于网络,
谁知道免费定位软件(谁知道免费定位)谁知道免费定位软件(谁知道免费定位)很多人在用微信附近的人的功能时,很希望自己的能够查看到任何位置附近的人。在微信聊天的功能中,一个比较好的功能就是分享自己的位置信息,这样能够方便
怎样不让对方定位我的位置(怎样不让对方定位)怎样不让对方定位我的位置(怎样不让对方定位)经常有粉丝私信联系我,出于某种原因需要对目标手机进行定位。今天我就来讲解一下手机定位原理,然后谈一谈到底能不能对目标手机进行定位。相关法
怎样不让对方定位我的位置(怎样不让对方定位我)怎样不让对方定位我的位置(怎样不让对方定位我)大家好,祝大家天天好心情。最近有朋友一直在问这个问题,怎么定位手机位置,实际上目前几乎所有品牌的手机都有这个功能,今天就分苹果手机和安
怎样不让对方定位我的位置(怎样不让对方定位)怎样不让对方定位我的位置(怎样不让对方定位)中国改革开放三十多年,取得了很大的成就,国际地位也越来越高。最让人欣慰的是,中国的科技水平相比以往取得了很大的进步,这种进步是世界都有目
怎样不让对方定位我的位置(怎样不让对方定位我)怎样不让对方定位我的位置(怎样不让对方定位我)节假日的时候,我们经常带着老人,散散步,逛逛超市或者出去游玩。人多的时候,很容易走散。但是当打电话的时候,说半天不知道对方在什么位置,
怎样不让对方定位我的位置(怎样不让对方定位)怎样不让对方定位我的位置(怎样不让对方定位)这年头,越来越多商业综合体遍布城市各大角落,集购物娱乐吃饭健身等于一体的商业综合体能给我们的生活带来不少便利,可问题来了,手机室内定位通
查号码能查出人在什么位置(怎么样用手机号码查找人位置)查号码能查出人在什么位置(怎么样用手机号码查找人位置)A个人认为Summer的用户可能更多是理智型。首先排除的就是游戏型,因为这是和Summer创始团队走心的初衷相违背的。然后关于
安卓手机定位怎么查到朋友的位置(知道手机号如何定位手机位置)安卓手机定位怎么查到朋友的位置(知道手机号如何定位手机位置)上周发布的苹果AirTag实现了应用精准定位,在杂乱无章的屋里能找到钱包和钥匙等。但是同时也带来了高精度定位侵犯隐私数据
手机如何实行跟踪定位(手机如何实行跟踪)手机如何实行跟踪定位(手机如何实行跟踪)你身边有没有这样的人?字典里好像永远没有方向这个词分不清路标,不会看路牌只知道前后左右,搞不懂南北东西然而,路痴或许不是你的错,而是你大脑中
手机如何实行跟踪定位(手机如何实行定位)手机如何实行跟踪定位(手机如何实行定位)随着移动互联网的发展,手机已经成为我们工作生活不可分割的一部分。如果手机不幸丢失,所有人都会很着急,都希望尽快找回来。而要找回来,就要找到手
送鲜花(如何正确的场合赠送合适的鲜花)送鲜花(如何正确的场合赠送合适的鲜花)给用花来表达的语言实在太丰富了,收花人的您可曾领会其中的深意?要送花的你,又是否有点困扰?如何正确的场合赠送合适的鲜花?不同场合如何送花?病人