首页 文章 精选 留言 我的

精选列表

搜索[优化],共10000篇文章
优秀的个人博客,低调大师

Android性能优化之内存泄漏

综述 内存泄漏(memory leak)是指由于疏忽或错误造成程序未能释放已经不再使用的内存。那么在Android中,当一个对象持有Activity的引用,如果该对象不能被系统回收,那么当这个Activity不再使用时,这个Activity也不会被系统回收,那这么以来便出现了内存泄漏的情况。在应用中内出现一次两次的内存泄漏获取不会出现什么影响,但是在应用长时间使用以后,若是存在大量的Activity无法被GC回收的话,最终会导致OOM的出现。那么我们在这就来分析一下导致内存泄漏的常见因素并且如何去检测内存泄漏。 导致内存泄漏的常见因素 情景一:静态Activity和View 静态变量Activity和View会导致内存泄漏,在下面这段代码中对Activity的Context和TextView设置为静态对象,从而产生内存泄漏。 importandroid.content.Context; importandroid.support.v7.app.AppCompatActivity; importandroid.os.Bundle; importandroid.widget.TextView; publicclassMainActivityextendsAppCompatActivity{ privatestaticContextcontext; privatestaticTextViewtextView; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); context=this; textView=newTextView(this); } } 情景二:Thread,匿名类,内部类 在下面这段代码中存在一个非静态的匿名类对象Thread,会隐式持有一个外部类的引用LeakActivity,从而导致内存泄漏。同理,若是这个Thread作为LeakActivity的内部类而不是匿名内部类,他同样会持有外部类的引用而导致内存泄漏。在这里只需要将为Thread匿名类定义成静态的内部类即可(静态的内部类不会持有外部类的一个隐式引用)。 publicclassLeakActivityextendsAppCompatActivity{ @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_leak); leakFun(); } privatevoidleakFun(){ newThread(newRunnable(){ @Override publicvoidrun(){ try{ Thread.sleep(Integer.MAX_VALUE); }catch(InterruptedExceptione){ e.printStackTrace(); } } }); } } 情景三:动画 在属性动画中有一类无限循环动画,如果在Activity中播放这类动画并且在onDestroy中去停止动画,那么这个动画将会一直播放下去,这时候Activity会被View所持有,从而导致Activity无法被释放。解决此类问题则是需要早Activity中onDestroy去去调用objectAnimator.cancel()来停止动画。 publicclassLeakActivityextendsAppCompatActivity{ privateTextViewtextView; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_leak); textView=(TextView)findViewById(R.id.text_view); ObjectAnimatorobjectAnimator=ObjectAnimator.ofFloat(textView,"rotation",0,360); objectAnimator.setRepeatCount(ValueAnimator.INFINITE); objectAnimator.start(); } } 情景四:Handler 对于Handler的内存泄漏在(Android的消息机制——Handler的工作过程)[http://blog.csdn.net/ljd2038/article/details/50889754]这篇文章中已经详细介绍,就不在赘述。 情景五:第三方库使用不当 对于EventBus,RxJava等一些第三开源框架的使用,若是在Activity销毁之前没有进行解除订阅将会导致内存泄漏。 使用MAT检测内存泄漏 对于常见的内存泄露进行介绍完以后,在这里再看一下使用MAT(Memory Analysis Tool)来检测内存泄露。MAT的下载地址为:http://www.eclipse.org/mat/downloads.php。 下面来看一段会导致内存泄露的错误代码。 publicclassLeakActivityextendsAppCompatActivity{ @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_leak); EventBus.getDefault().register(this); } @Subscribe publicvoidsubscriber(Strings){ } } 在上面这段代码中有会导致内存泄漏,原因是EventBus没有解除注册。下面就以这段代码为例来看一下如何分析内存泄漏。 打开AndroidStudio中的Monitors可以看到如下界面。 在这里可以看到在应用刚启动的时候,所占用的内存为15M,然后我们现在开始操作APP,反复进入退出LeakActicity。点击上如中的GC按钮。这时候我们在看一下内存使用情况。 在这里我们可以看到,内存一直在持续增加,已经达到33M,并且无法被GC所回收。所以我们可以判断,这时候必然出现内存泄漏的情形。那么现在再点击Dump Java Heap按钮,在captures窗口看到生成得hprof文件。但这时候所生成的hprof文件不是标准格式的,我们需要通过SDK所提供的工具hprof-conv进行转化,该工具在SDK的platform-tools目录下。执行命令如下: hprof-convXXX.hprofconverted-dump.hprof 当然在AndroidStudio中可以省去这一步,可以直接导出标准格式的hprof文件。 这时候可以通过MAT工具来打开导出的hprof文件。打开界面如下图所示: 在MAT中我们最常用的就是Histogram和Dominator Tree,他们分别对应上图中的A和B按钮。Histogram可以看出内存中不同类型的buffer的数量和占用内存的大小,而Dominator Tree则是把内存中的对象按照从大到小的顺序进行排序,并且可以分析对象之间的引用关系。在这里再来介绍一下MAT中两个符号的含义。 ShallowHeap:对象自身占用的内存大小,不包括他引用的对象 RetainedHeap:对象自身占用的内存大小并且加上它直接或者间接引用对象的大小 Histogram 由于在Android中一般内存泄漏大多出现在Acivity中,这时候可以点击Histogram按钮,并搜索Activity。 在这里可以看出LeakActivity存在69个对象,基本上可以断定存在内存泄漏的情形,这时候便可以通过查看GC对象的引用链来进行分析。点击鼠标右键选择Merge Shortest paths to GC Roots并选择exclude weak/soft references来排除弱引用和软引用。 在排除软引用和弱引用以后如下图所示: 在这里可以看出由于EventBus导致的LeakActivity内存泄漏。 在Histogram中还可以查看一个对象包含了那些对象的引用。例如,现在要查看LeakActivity所包含的引用,可以点击鼠标右键,选择list objects中的with incoming reference。而with outcoming reference表示选中对象持有那些对象的引用。 Dominator Tree 现在我们点击这时候可以点击Dominator Tree按钮,并搜索Activity。可以看到如下图所示: 在这里可以看到存在大量的LeakActivity。然后点击鼠标右键选择Path To GC Roots->exclude weak/soft references来排除弱引用和软引用。 exclude weak/soft references来排除弱引用和软引用" title="点击鼠标右键选择Path To GC Roots->exclude weak/soft references来排除弱引用和软引用" style="border:none;" data-original="http://s3.51cto.com/wyfs02/M00/8B/E2/wKioL1hbrCjTNwxTAAJ1gvALA-c226.jpg"> 之后可以看到如下结果,依然是EventBus导致的内存泄漏: 总结 内存泄漏往往被我们所忽略,但是当大量的内存泄漏以后导致OOM。它所造成的影响也是不容小觑的。当然除了上述内存泄漏的分析以为我们还可以通过LeakCanary来分析内存泄漏。对于LeakCanary的使用在这里就不在进行详细介绍。 本文作者:佚名 来源:51CTO

优秀的个人博客,低调大师

IOS-内存检测以及优化

PS:开始写这个系列的笔记:主要是对过去自己比较模糊的一些概念进行 测试,明确结果,提高自己 IOS 应用如果占用系统的内容过大(8GB),就会造成应用直接被系统以崩溃的形式关闭,一次控制应用占用的内存大小是非常重要的事情。 现在我们来看看,一个空的应用占据的内容的大小: 测试环境:xCode 5.0/IOS 5 启动一个空应用,占用的内存为 2.6MB,占据应用崩溃的阀值为 0.03% 1:关于导航条的 Push和popup的测试结果 [self.navigationController pushViewController:m_navanimated:YES]; [self.navigationController popViewControllerAnimated:YES]; 对于 pushViewController ,会将对应的ViewController对象的引用计数器+1 popViewControllerAnimated 会将对应的ViewController对象的引用计数器-1 但是有一点需要明确的是,对于函数 -(void)dealloc { //Objects release here [super deallco]; } 只有在该引用计数器的值==0的时候才会调用,这个是必须牢记的。 在执行函数[self.navigationController popViewControllerAnimated:YES];的时候,如果弹出的ViewController对应的引用计数器为0,那么也会执行dealloc 函数。 所以再使用 [self.navigationController pushViewController:m_navanimated:YES]; [self.navigationController popViewControllerAnimated:YES]; 栈函数对的时候,为了释放内存,我们可以这么使用 Nav_1 *m_nav = [[[Nav_1 alloc] initWithNibName:nil bundle:nil] autorelease]; [self.navigationController pushViewController:m_nav animated:YES]; 这样就最大限度的节省了宝贵的内存空间 最新内容请见作者的GitHub页:http://qaseven.github.io/

优秀的个人博客,低调大师

MaxCompute基础与MaxCompute SQL优化

总论: 大数据计算服务 ( MaxCompute,原名 ODPS ) 是一种快速、完全托管的 TB/PB 级数据仓库解决方案 。MaxCompute 向用户提供了完善的数据导入方案以及多种经典的分布式计算模型,能够更快速的解决用户海量数据计算问题,有效降低企业成本,并保障数据安全 。同时,大数据开发套件和 MaxCompute关系紧密,大数据开发套件为 MaxCompute 提供了一站式的数据同步,任务开发,数据工作流开发,数据管理和数据运维等功能,您可以参见大数据开发套件简介来对其进行深入了解 。 MaxCompute 主要服务于批量结构化数据的存储和计算,可以提供海量数据仓库的解决方案以及针对大数据的分析建模服务 。随着社会数据收集手段的不断丰富及完善,越来越多的行业数据被积累下来 。数据规模已经增长到了传统软件行业无法承载的

优秀的个人博客,低调大师

优化Hadoop Balancer运行速度

1.修改dfs.datanode.max.transfer.threads = 4096 (如果运行hbase的话建议为16384),指定用于在DataNode间传输block数据的最大线程数,老版本的对应参数为dfs.datanode.max.xcievers 2.修改dfs.datanode.balance.bandwidthPerSec =52428800,指定DataNode用于balancer的带宽为50MB,这个示情况而定,如果交换机性能好点的,完全可以 设定为100MB,单位是Byte,如果机器的网卡和交换机的带宽有限,可以适当降低该速度,默认是1048576(1MB) 3.修改dfs.datanode.balance.max.concurrent.moves = 50,指定DataNode上同时用于balance待移动block的最大线程个数,这个值默认是5 如果配置没生效或者不合理的话,Balancer会有如下警告信息: 16/05/17 11:54:59 WARN balancer.Dispatcher: Failed to move blk_1075360746_1920035 with size=134217728 from 192.168.28.48:50010:DISK to 192.168.28.37:50010:DISK through 192.168.28.40:50010: Got error, status message opReplaceBlock BP-647596829-192.168.28.30-1448614319339:blk_1075360746_1920035 received exception java.io.IOException: Got error, status message Not able to copy block 1075360746 to /192.168.28.37:39630 because threads quota is exceeded., copy block BP-647596829-192.168.28.30-1448614319339:blk_1075360746_1920035 from /192.168.28.40:50010, block move is failed Hadoop Balancer的步骤: 1、从namenode获取datanode磁盘的使用情况2、计算需要把哪些数据移动到哪些节点3、分别移动,完成后删除旧的block信息4、循环执行,直到达到平衡标准

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册