Android内存管理哪些事

上一篇文章总结了一下内存分析的方法,这次聊聊如何出现解决和避免内存相关的问题。

 上一篇文中我们提到,出现OOM通常是因为有内存泄漏或是内存使用不当(分配了过多的内存),在Android的早期时代,内存真是非常的珍贵啊,大部分是手机只有32或24M的heapsize,记得曾经有一个项目,有图片处理的逻辑,运行几分种就会OOM,很多人就说是有内存泄露,后来排查了半天,发现是处理的速度跟不上加载的速度,消耗了太多的内存导致,现在主流的手机heapsize基本上都有64M,应该来讲,只要没有内存泄漏,很少会发生OOM的,并且,从Android 3.0开始,引入了largeheap,就是说你在manifest的application TAG中加入 android:largeHeap="true" 之后就可以让你的应用申请更多的内存(每个手机定义的大小不尽相同),标准的heapsize和largeHeap都可以通过方法查询的到:

 

                ActivityManager mgr = (ActivityManager)  MainActivity.this
                        .getSystemService(Context.ACTIVITY_SERVICE);
                Log.d(TAG,  "MemoryClass is:"+mgr.getMemoryClass()+",large class is:"+mgr.getLargeMemoryClass());
 你的应用到底有多少的heapsize可以通过:

 

 final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
来获取(注意,这里的单位是K)
我测试了几个手机,Galaxy nexus 可以申请到256M的heapsize,256M啊,同学们,这是多么的奢侈啊,但是人家谷歌说的很清楚,用这个标签一定要慎重,除非你是真的需要这么多内存,不能把这玩意作为快速解决OOM的手段,如果你的内存使用过多,还是先慎重的分析一下你的内存到哪里去了,因为这会导致GC的时间较长并且会影响系统的性能,原文如下:
However, the ability to request a large heap is intended only for a small set of apps that can justify the need to consume more RAM (such as a large photo editing app). Never request a large heap simply because you've run out of memory and you need a quick fix—you should use it only when you know exactly where all your memory is being allocated and why it must be retained. Yet, even when you're confident your app can justify the large heap, you should avoid requesting it to whatever extent possible. Using the extra memory will increasingly be to the detriment of the overall user experience because garbage collection will take longer and system performance may be slower when task switching or performing other common operations
无论手机的内存有多大,请记住,这只是手机,一定要珍惜内存。
那怎么样能够减少内存的使用呢,我个人认为,可以从以下几个方面入手:
  • 避免内存泄漏
  • 能不创建的对象就不要创建
  • 合理管理对象生命周期
  • 科学设计应用背景图片(尽量使用.9.png图片)

避免内存泄漏

首先是一定要避免内存泄漏,如果存在内存泄漏,多少内存也不够用,关于Java为什么会有内存泄漏以及内存泄露的定义IBM网站上有一篇文章说的非常到位:http://www.ibm.com/developerworks/cn/java/l-JavaMemoryLeak/

这里摘录一下该文的重点:

在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;其次,这些对 象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占 用内存。

图2

GC是如何工作的呢:

文章也很好的交代了这一点:

为了更好理解GC的工作原理,我们可以将对象考虑为有向图的顶点,将引用关系考虑为图的有向边,有向边从引用者指向被引对象。另外,每个线程对象可 以作为一个图的起始顶点,例如大多程序从main进程开始执行,那么该图就是以main进程顶点开始的一棵根树。在这个有向图中,根顶点可达的对象都是有 效对象,GC将不回收这些对象。如果某个对象 (连通子图)与这个根顶点不可达(注意,该图为有向图),那么我们认为这个(这些)对象不再被引用,可以被GC回收。

图1

这些问题阐述清楚之后我们来看看Android平台常见的导致内存泄漏的原因(基本上都是在以往的项目中碰到的):

1.registerContentObserver未解注册(观察者模式要小心,切记适时解注册);

2.没有关闭(一定要在finally中关闭)cursor,这里要多说一点的是,我们其实可以用AsyncQueryHandler或者CursorLoader 等数据库异步加载框架避免在activity中对cursor的管理;

3.Adapter bindview实现不当,这个属于比较低级的,但是还是有人会这么干,就是在bindview里不去判断convertview直接创建,关于怎么实现这里不再多讲;

4.单例模式注册listener未解注册;

5.mTelePhonyMgr.listen(mListener,PhoneStateListener.LISTEN_NONE);貌似这么调用之后不能解注册,不知道4.0以后的版本有没有修改。

大部分的问题都跟static有关,一旦声明成static,除非我们主动的设置为null,否则是无法被回收的,像单例,观察者这些设计模式,通常都有生命周期较长的一方,使用的时候一定要小心。

能不创建的对象就不要创建

其实很多时候我们一个不小心的举动就会创建过多的对象,比如下面的这段代码:

public class DataBean {
    private String mData = "";
    private ArrayList<DataB> mDataBs = new ArrayList<DataB>();
}

 这就是很不好的编程习惯,如果这些字段为空,就无端的多创建了很多的对象,如果我们在内存中又加载了大量这样的对象,。。。。浪费啊。

再比如说,通常我们有一些比较复杂的界面,布局文件会比较庞大,常常会通过逻辑的需要来控制不同元素的可见性,这时候如果我们采用viewstub,在需要的时候再加载相应的布局,就可以避免创建无用的对象,也可以加快activity的加载速度。:

写道
<ViewStub android:id="@+id/stub"
android:inflatedId="@+id/subTree"
android:layout="@layout/mySubTree"
android:layout_width="120dip"
android:layout_height="40dip" />

 

另外,有时候我们可以通过复用对象来达到少创建对象的目地,比如当我们有大量的数据需要插入到数据库时,

我们就可以这么做:

private ContentValues mValues = new ContentValues();

    public void inserVaules(String value1,int vaule2){
        mValues.clear();
        mValues.put(key, value1);
        mValues.put(key, vaule2);
        this.getContentResolver().insert(url, values);
       
    }

 

 合理管理对象生命周期:

这个通常在架构阶段就要考虑清楚,我们有哪些东西是要常驻内存的,有哪些是伴随界面存在的,尤其是那些缓存和业务逻辑层的manager,在做缓存的时候一定要平衡好内存和性能,关于一些缓存资源的释放推荐看一下Android新引入的onTrimMemory() 方法,目前源码中已经有部分的逻辑实现了该方法

比如系统luncher中:

@Override
public void onTrimMemory(int level) {
 super.onTrimMemory(level);
 if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
 mAppsCustomizeTabHost.onTrimMemory();
 }
 }

 

    public void onTrimMemory() {
        mContent.setVisibility(GONE);
        // Clear the widget pages of all their subviews - this will trigger the widget previews
        // to delete their bitmaps
        mAppsCustomizePane.clearAllWidgetPages();
    }

 AppsCustomizePagedView.java

 

 

   public void clearAllWidgetPages() {
        cancelAllTasks();
        int count = getChildCount();
       for (int i = 0; i < count; i++) {
       View v = getPageAt(i);
            if (v instanceof PagedViewGridLayout) {
                ((PagedViewGridLayout) v).removeAllViewsOnPage();
                mDirtyPageContent.set(i, true);
            }
        }
    }

    private void cancelAllTasks() {
        // Clean up all the async tasks
        Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator();
        while (iter.hasNext()) {
            AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next();
           task.cancel(false);
            iter.remove();
            mDirtyPageContent.set(task.page, true);

            // We've already preallocated the views for the data to load into, so clear them as well
            View v = getPageAt(task.page);
            if (v instanceof PagedViewGridLayout) {
                ((PagedViewGridLayout) v).removeAllViewsOnPage();
            }
        }
        mDeferredSyncWidgetPageItems.clear();
        mDeferredPrepareLoadWidgetPreviewsTasks.clear();
    }

 

 科学设计应用背景图片

这个不用做过多的阐述,凡事都是有代价的,太炫太复杂太大太多的背景图片会导致应用耗用过多的内存。

另外,谷歌也给出了一些节省内存的tips:

比如stringbuffer啊,尽量用int基本类型而不是Integer等。

 

 

智慧旅游解决方案利用云计算、物联网和移动互联网技术,通过便携终端设备,实现对旅游资源、经济、活动和旅游者信息的智能感知和发布。这种技术的应用旨在提升游客在旅游各个环节的体验,使他们能够轻松获取信息、规划行程、预订票务和安排食宿。智慧旅游平台为旅游管理部门、企业和游客提供服务,包括政策发布、行政管理、景区安全、游客流量统计分析、投诉反馈等。此外,平台还提供广告促销、库存信息、景点介绍、电子门票、社交互动等功能。 智慧旅游的建设规划得到了国家政策的支持,如《国家中长期科技发展规划纲要》和国务院的《关于加快发展旅游业的意见》,这些政策强调了旅游信息服务平台的建设和信息化服务的重要性。随着技术的成熟和政策环境的优化,智慧旅游的时机已经到来。 智慧旅游平台采用SaaS、PaaS和IaaS等云服务模式,提供简化的软件开发、测试和部署环境,实现资源的按需配置和快速部署。这些服务模式支持旅游企业、消费者和管理部门开发高性能、高可扩展的应用服务。平台还整合了旅游信息资源,提供了丰富的旅游产品创意平台和统一的旅游综合信息库。 智慧旅游融合应用面向游客和景区景点主管机构,提供无线城市门户、智能导游、智能门票及优惠券、景区综合安防、车辆及停车场管理等服务。这些应用通过物联网和云计算技术,实现了旅游服务的智能化、个性化和协同化,提高了旅游服务的自由度和信息共享的动态性。 智慧旅游的发展标志着旅游信息化建设的智能化和应用多样化趋势,多种技术和应用交叉渗透至旅游行业的各个方面,预示着全面的智慧旅游时代已经到来。智慧旅游不仅提升了游客的旅游体验,也为旅游管理和服务提供了高效的技术支持。
智慧旅游解决方案利用云计算、物联网和移动互联网技术,通过便携终端设备,实现对旅游资源、经济、活动和旅游者信息的智能感知和发布。这种技术的应用旨在提升游客在旅游各个环节的体验,使他们能够轻松获取信息、规划行程、预订票务和安排食宿。智慧旅游平台为旅游管理部门、企业和游客提供服务,包括政策发布、行政管理、景区安全、游客流量统计分析、投诉反馈等。此外,平台还提供广告促销、库存信息、景点介绍、电子门票、社交互动等功能。 智慧旅游的建设规划得到了国家政策的支持,如《国家中长期科技发展规划纲要》和国务院的《关于加快发展旅游业的意见》,这些政策强调了旅游信息服务平台的建设和信息化服务的重要性。随着技术的成熟和政策环境的优化,智慧旅游的时机已经到来。 智慧旅游平台采用SaaS、PaaS和IaaS等云服务模式,提供简化的软件开发、测试和部署环境,实现资源的按需配置和快速部署。这些服务模式支持旅游企业、消费者和管理部门开发高性能、高可扩展的应用服务。平台还整合了旅游信息资源,提供了丰富的旅游产品创意平台和统一的旅游综合信息库。 智慧旅游融合应用面向游客和景区景点主管机构,提供无线城市门户、智能导游、智能门票及优惠券、景区综合安防、车辆及停车场管理等服务。这些应用通过物联网和云计算技术,实现了旅游服务的智能化、个性化和协同化,提高了旅游服务的自由度和信息共享的动态性。 智慧旅游的发展标志着旅游信息化建设的智能化和应用多样化趋势,多种技术和应用交叉渗透至旅游行业的各个方面,预示着全面的智慧旅游时代已经到来。智慧旅游不仅提升了游客的旅游体验,也为旅游管理和服务提供了高效的技术支持。
深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值