Android 内存浅析【二】【泄漏、溢出】

浅析Context及可能带来的内存泄漏问题 什么是 Context纯英文含义来看,Context 意指上下文、环境、背景等等……那么 Android 中的 Context 的含义和这些英文释义有什么联系呢?不妨看看 Google 给出的定义: Interface to global information about an application environment. This is an abstract class whose i 阅读详情

继续,这张说说一些android中泄漏和溢出的细节点:

一、泄漏根源之Static
    static是Java中的一个关键字,当用它来修饰成员变量时,那么该变量就属于该类,而不是该类的实例。所以用static修饰的变量,它的生命周期是很长的,如果用它来引用一些资源耗费过多的实例(Context的情况最多),这时就要谨慎处理。

[java]  view plain copy
  1. public class Example {    
  2.      private static Context mContext;    
  3.      //省略    
  4. }  
以上的代码一般看来似乎没什么问题。但如果将Activity赋值到么mContext的话。那么即使该Activity已经onDestroy,但是由于仍有对象保存它的引用,因此该Activity依然不会被释放。

还没完呢,再看看下边的:

[java]  view plain copy
  1. private static Drawable sBackground;    
  2.       
  3.     public void example (){  
  4.         ImageView iv = new ImageView(this);  
  5.         iv.setBackgroundDrawable(sBackground);  
  6.     }  

 我发现有很多哥们都这么写,同样看起来没什么问题,但我们来剖析一下:sBackground, 是一个静态的变量,但是我们发现,我们并没有显式的保存Contex的引用,但是,因为Imageview是View的子类,当Drawable与View连接之后,Drawable就将View设置为一个回调:

[java]  view plain copy
  1. public class View implements Drawable.Callback  
  2.   
  3. /** 
  4.      * The application environment this view lives in. 
  5.      * This field should be made private, so it is hidden from the SDK. 
  6.      * {@hide} 
  7.      */  
  8.     protected Context mContext;  

由于View中是包含Context的引用的,所以,实际上我们依然保存了Context的引用。所以最终的引用链如下:
    Drawable->ImageView->Context

    所以,最终该Context也没有得到释放,积累就发生了内存泄露。
    如何才能有效的避免这种引用的发生呢?
    第一,应该尽量避免static成员变量引用资源耗费过多的实例,比如Context。
    第二、Context尽量使用Application Context,因为Application的Context的生命周期比较长(具体多次不作详细解释,各位去看文档)。
    第三、使用WeakReference代替强引用。比如可以使用WeakReference<Context> mContextRef(一位前辈提起的,具体不是很清楚,也在琢磨中)


二、泄漏根源之线程
    线程也是造成内存泄露的一个重要的源头。线程产生内存泄露的主要原因在于线程生命周期的不可控。先看段代码。

[java]  view plain copy
  1. new Thread(new Runnable() {  
  2.             public void run() {  
  3.                 // TODO do something  
  4.             }  
  5.         }).start();  

   很平常的一段代码是吧,也是咱经常这么搞的。假设问题:假设run函数是一个很费时的操作(通常大数据的加载),在加载过程中(前提线程并没有结束),将设备的竖屏变为了横屏,一般情况下当屏幕转换时会重新创建Activity(当然你也可以设置不创建新的Activity,在此以创建新的为论点),按照我们的想法,老的Activity应该会被销毁才对,然而事实上并非如此。


    由于我们的线程是Activity的内部类,所以Thread中保存了Activity的一个引用,当Thread是不会被销毁的直至run函数结束时,因此它所引用的老的Activity也不会被销毁,因此就出现了内存泄露的问题。

有些人喜欢用Android提供的AsyncTask,但事实上AsyncTask的问题更加严重,Thread只有在run函数不结束时才出现这种内存泄露问题,然而AsyncTask内部的实现机制是运用了ThreadPoolExcutor,该类产生的Thread对象的生命周期是不确定的,是应用程序无法控制的,因此如果AsyncTask作为Activity的内部类,就更容易出现内存泄露的问题。
    这种线程导致的内存泄露问题应该如何解决呢(引用前辈的话)?
    第一、将线程的内部类,改为静态内部类。
    第二、在线程内部采用弱引用保存Context引用。

[java]  view plain copy
  1. public class ExampleAsyncTask<Params, Progress, Result, WeakTarget> extends  
  2.             AsyncTask<Params, Progress, Result> {  
  3.           
  4.         @Override  
  5.         protected final Result doInBackground(Params... params) {  
  6.             //TODO: do something  
  7.             return null;  
  8.         }  
  9.     }  

小结: 事实上,线程的问题并不仅仅在于内存泄露,还会带来一些灾难性的问题。例如:多线程并发安全(推荐下载张孝祥的多线程并发视频,十分详细)等等
Android性能优化之内存优化浅析 一、背景 Android由于是以Java语言为主要开发语言,所以它的内存管理并不像C语言那样由开发者去管理内存的分配以及回收等,而是交由JVM虚拟机的内存回收机制去处理。这就导致我们在开发过程中难免会遇到内存相关的各种问题带来的困扰。而这些问题的根源就在于我们对Android的内存管理机制的不够了解,以及开发过程中缺少对内存的关注导致。所以这里借这篇文章我们再回顾一下Android的内存管理机制,以及如何在开发过程中去尽量避免这些内存问题。 二、内存管理—内存划分 Android中的内... 阅读详情

相关推荐

航空大数据——项目资源汇总及开源(四)

ADS-B项目开源大礼包

cyc头发还挺多的博客 4986

Android 内存浅析【泄漏、溢出】【一】

继续,这张说说一些android中泄漏和溢出的细节点: 一、泄漏根源之Static     static是Java中的一个关键字,当用它来修饰成员变量时,那么该变量就属于该类,而不是该类的实例。所以用static修饰的变量,它的生命周期是很长的,如果用它来引用一些资源耗费过多的实例(Context的情况最多),这时就要谨慎处理。 public class Example {

老牛比 3469

PLC编程入门基础知识

PLC即为可编程逻辑控制器,实质是一种专用于工业控制的计算机,其硬件结构基本上与微型计算机相同。

SANRENYIXING的博客 2万+

android中常见的内存泄漏和解决办法

android中的内存溢出估计大多数人在写代码的时候都出现过,其实突然觉得工作一年和工作三年的区别是什么呢,其实干的工作也许都一样,产品汪看到的结果也都一样,那区别就是速度和质量了。写在前面的一点儿想法:工作做完了其实不会的还有很多,每天都有莫名的危机感,从真正写代码的这一年多总觉得自己的学习速度比别人的慢很多内存溢出是什么鬼? 当某些对象不再被程序所使用,但是这些对象仍然被某些对象所引用着,进而导

svenWang_的专栏 1万+

12V转5V稳压电路详细分析(7805三端稳压,LM2596稳压)

7805线性三端稳压 DCDC的意思是直流变到直流(不同直流电源值的转换),只要符合这个定义都可以叫DCDC转换器,或称之为开关电源或开关调整器。 7805属于常用的线性三端稳压器,输入电压范围不大于35V,输入输出压差2V,最大输出电流1.5A,下图为原理图,其原理简单,使 用方便,深受很多用户的喜爱。但是其不足之处就是效率低,特别是压差越大时其效率越低。比如这里12V转5V的效率为 5V/12V≈41.7%。 如上电路是最经典的7805稳压5V电路,电路中有两个电容,电容的作用如下: ...

a2001444的博客 9万+

银河麒麟V10SP1实战:5步搞定AD域登录(附Samba+Winbind配置详解)

本文提供银河麒麟V10 SP1操作系统无缝集成Windows AD域的实战指南。文章深入解析了Samba、Winbind与Kerberos三大核心组件的协作原理,并详细阐述了从环境准备、软件包安装、配置文件定制到执行加域及排错的全流程。特别针对2403等新版本提供了关键配置差异与避坑要点,旨在帮助企业运维人员实现高效、稳定的域环境登录与管理。

weixin_29269441的博客 293

Android中使用Thread造成内存泄露的分析和解决

Thread 内存泄露线程也是造成内存泄露的一个重要的源头。线程产生内存泄露的主要原因在于线程生命周期的不可控。看一下下面是否存在问题 public class ThreadActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreat

Dream It Possible 1万+

Unreal5从入门到精通之如何在VR中使用3DUI

前面我们讲过《Unreal5从入门到精通之UMG的使用》一般制作游戏时,UI都是添加到屏幕视窗上面的,但是在制作VR时,我们往往需要制作一个3D的UI,放置在场景中,然后使用手柄的射线来和UI进行交互。今天我们就来讲解下,如何在VR中创作和交互3DUI首次操作会感觉好复杂,多多练习,当你熟悉了UE蓝图的操作后会发现,这只是一个常规的蓝图操作而已。祝大家在虚幻的学习过程中非常顺利。希望这篇博客对你有所帮助。

TxNet 1985

记一次多线程溢出问题

解决问题也是会上瘾的。 按照惯例,先抛问题。 问题 我们线上环境,重新部署了数据处理流程的项目,但是,没过几天,大数据平台开始不正常了。表现出来的现象就是,ambari-agent节点失联,其他组件的节点挂了(hbase,hdfs),总之是各种预警。因为我是这边大数据的开发兼职运维(很惨),线上平台出现问题,赶紧去看了一波,系统性能,没问题。节点日志(后来看部分节点日志暴露了问题,所以日志真的很重...

ycccsdn的博客 1093

使用Qt在FreeRTOS上构建MCU应用程序

如果我们想要在FreeRTOS上运行该应用程序,我们需要选择适用于我们处理器架构的交叉编译工具链,并将目标设备设置为我们的开发板。在该代码中,我们使用xTaskCreate()函数创建了一个名为“qt_task”的任务,并将其启动。首先,我们需要安装Qt for MCU开发环境。Qt for MCU是基于Qt 5开发的针对MCU的特殊版本,它可以生成最小体积的代码,从而适用于资源有限的嵌入式系统。如果我们想要在FreeRTOS上运行这个程序,我们需要将其包装在一个任务中,并在任务创建后启动Qt的事件循环。

ByteWhizX的博客 1815

AIGC时代的必备技能:提示词工程(Prompt Engineering)全面指南

本文主要介绍了AIGC时代的重要技能——提示词工程(Prompt Engineering)。文章首先定义了提示词的概念,强调其作为人类与AI沟通桥梁的重要性,并详细阐述了提示词的功能特性,包括输入、大模型处理和输出三个环节。接着,文章探讨了提示工程的重要性,如提高输出质量、节省资源和时间等。随后,文章深入分析了提示词的基本构成要素,包括指令、上下文、输入数据和输出指示符,并提出了提示词的五大基本原则:清晰性与具体性、提供充足的上下文、明确任务与目标、考虑受众和迭代思维。最后,文章介绍了提示词的七大常见技巧

weixin_43178406的博客 27万+

Android 让你的 Room 搭上 RxJava 的顺风车 从重复的代码中解脱出来

什么是 Room ? 谷歌为了帮助开发者解决 Android 架构设计问题,在 Google I/O 2017 发布一套帮助开发者解决 Android 架构设计的方案:Android Architecture Components,而我们的 Room 正是这套方案的两大模块之一。 定义:数据库解决方案 组成:Database、Entity、DAO 为什么本文叫谷歌范例? 为了方便开发者进行...

圆号本号 1271

28_Spring AI 干货笔记之 OpenAI 聊天功能

本文详细介绍了在Spring AI框架中集成OpenAI聊天模型的方法。内容涵盖API密钥配置、通过starter依赖启用自动配置、连接与模型参数的详细设置,并重点说明了运行时选项的动态覆盖机制。文章还深入讲解了多模态处理(图像与音频)、结构化输出、函数调用等高级功能,提供了示例控制器和手动配置指南,并讨论了与OpenAI兼容服务器的适配与推理模型思维链的获取。

在科技的浪潮中,我们寻找着创新的火种,在代码的海洋里,我们编织着智慧的网。腾飞开源,就是这样一个由技术精英汇聚而成的博客平台,我们致力于分享在Java、Python、IoT和人工智能等领域的最新研究成果和实战经验。 在腾飞开源的博客上,你会看到紧跟技术前 1657

Android 内存浅析【泄漏、溢出】【二】

内存溢出之Bitmap      可以说出现OutOfMemory问题的绝大多数人,都是因为Bitmap的问题。因为Bitmap占用的内存实在是太多了,它是一个“超级大胖子”,特别是分辨率大的图片,如果要显示多张那问题就更显著了。     如何解决Bitmap带给我们的内存问题?     第一、及时销毁。     虽然,系统能够确认Bitmap分配的内存最终会被销毁,但是由于它占用的内存过

老牛比 4413

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

android对象引用释放,Android开发中内存泄漏浅析

一.什么是内存泄漏众所周知,为了合理利用内存空间,不再被使用的对象应该被系统回收从而释放内存,这是所有面向对象编程的共识。在java中,有一套完整的GC回收机制来管理上述事务。然而,在实际开发过程中,我们常常遇到在应用程序运行时,符合上述条件的对象无法被回收,长期占用有限的内存空间,这种现象就被称为内存泄漏。二.内存泄漏产生的影响要描述内存泄漏产生的影响,我们首先要理解另外一个概念:内存溢出。当初...

weixin_29775447的博客 407

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

内存抖动是什么?怎么解决?内存溢出是什么?怎么解决?垃圾回收机制是什么样的?

1. JVM内存泄漏与内存溢出的区别? 2. 内存抖动是什么?怎么解决? 3. 垃圾回收机制是什么样的?

sunlifeall的博客 4391

【android开发】Android防止内存溢出浅析

最近项目做得差不多了,测试出现了一些问题,其中一个就是内存溢出问题,在三星手机上测试最容易出现内存溢出,在其他手机上,比如华为就没有发生,也是比较郁闷。这个问题在之前的公司,做项目时也遇到过,很大一方面是自己写的代码问题,今天在网上找了一些知识,给大家分享一下: Android的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M。但是Android采用的是Java语言编

编程的初衷是什么? 1053

浅析android的内存泄漏

Android内存优化 一、浅析Android开发中常见的内存泄漏 首先我们来解释下两个名词: 内存泄漏 当一个对象在程序执行过后已经不需要再使用了,但是有其他的对象还持有该对象的引用,以致该对象不能被GC回收,那么这个对象会一直占用内存,从而导致该内存不可用,这种本该被GC回收(不再需要用了)而又不能被回收(被其他对象持有引用),以致停留在堆内存中的对象就造成了内存泄露. ...

bencheng06的博客 267

android防止内存溢出浅析(二)

上次讨论的 由于Bitmap引起的内存溢出相对比较容易发现,这次我们来看看相对比较难以发现的引起内存溢出的两种情况。 一,Context引起的内存溢出: 在Android平台上,长期保持一些资源的引用,造成一些内存不能释放,带来的内存泄露问题很多。比如Context。 android中的很多资源文件都需要一个Context引用来加载,如果这些资源没有被释放,那么Context的引用不为n

bingdongguke的专栏 1044

Android 内存浅析

一、 Android的内存机制     Android的程序由Java语言编写,所以Android的内存管理与Java的内存管理相似。程序员通过new为对象分配内存,所有对象在java堆内分配空间;然而对象的释放是由垃圾回收器来完成的。C/C++中的内存机制是“谁污染,谁治理”,java的就比较人性化了,给我们请了一个专门的清洁工(GC)。 二、GC是什么? 为什么要有GC?

cy-app 981

android防止内存溢出浅析(一)

做android游戏开发有一段时间了,对于开发中遇到额OutOfMemory 异常真的是很头疼,今天就在此总结下。 游戏开发中遇到的内存溢出基本上都是出现在加载Bitmap的时候 ,原因是Bitmap实在是太占内存了,尤其是对于高分辨率的的图片一定要小心使用了。 下面就罗列出三点解决使用Bitmap时出现的内存溢出问题的方案: 一.及时的销毁: 虽然,系统能够确认Bitmap分配的内存最终

bingdongguke的专栏 1052

关于Android开发ListView复用的浅析

关于Android开发ListView复用的浅析 做项目时碰到了显示ListView时如何通过BaseAdapter的重写getView方法来达到内存回收的目的,防止内存泄漏和溢出。这里记录一下自己的理解。 首先为了不频繁获取布局界面的id,先写一个内部类来绑定控件的ID,在重写的getView方法中,先定义一个该类的对象,然后判断是否是第一次创建该ListView对象: ViewHolde...

qq_43467917的博客 327

安卓开发中防止内存溢出浅析

安卓的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M。但是安卓采用的是Java语言编写,所以在很大程度上,安卓的内存机制等同于Java的内存机制,在刚开始开发的时候,内存的限制问题会给我们带来内存溢出等严重问题。在我们不使用一些内存的时候,我们要尽量在Android或者其他平台上避免在运行其他程序时,保存必要的状态,使得一些死进程所带来的内存问题,应该尽量在关闭程序或者保存状态的时候

maohuihua的专栏 307
上一篇: Android 内存浅析【一】【管理、机制、分析】
下一篇: Android 实用工具Hierarchy Viewer实战
祝福
博客等级 码龄15年 263粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值