内存泄漏如何解决有哪些场景以及解决方法

天极传媒:天极网全国分站
您现在的位置:
& >&解决续航问题四大场景告诉你最佳方案
如何解决续航问题四大场景告诉你最佳方案天极网手机频道 10:11
  在科技飞速发展的今天,对于一些大众类的商品,本来是不应该有什么大瓶颈的,但偏偏在普及率极高的智能发展上,就有一项技术成为了制约的瓶颈,那就是。
  不论是智能手机的领导者,还是华强北作坊的贴牌智能机,都逃不过这样的命运,虽然苹果在各方面都做得比较出色了,但仍然还是必须一天一充,包括最新的苹果表被人诟病最多的也是问题,而华强北作坊尽管打造了无数匪夷所思的作品,但在续航上也无能为力,只能通过内置极其危险的数万毫安电池去弥补。
  就目前而言一般厂商都会通过两种方法来解决耗电问题,一是通过内置安全的大电池,并优化系统进而达到省电的目的,二是通过特殊的充电器(或充电结构),来达到快速充电,从而解决电量不足的情况。那么,到底哪种解决方案更加实用呢?我们不妨来盘点一下经常遇到的没电的情况。
  一、外出一整天
  这应该是最常见的情况了,绝大部分人在面临一整天出行的时候,都会选择,但上万毫安的移动动辄一斤的重量,也是蛮可怕的,是最不可取的行为。而如果选择了带有快充的智能手机,例如,那么就可以省掉携带移动电源的不便,虽然可能需要携带特殊的快充充电器,但其重量要轻很多,不过寻找充电插座又是一个比较麻烦的事情,尽管一般来说,充半小时约可以达到70%左右的电量,但前提是必须有地方去充电,这在国内绝大部分地方,还是比较困难的。
  而相对来说,大容量电池的智能手机优越性就比较明显了,例如最新推出的铂金版,其达到了4150毫安,虽然不能达到购物中一年待机的水平,但用几天是问题不大的。据vivo官方表示,其待机时间可达430小时,对于智能手机来说非常不可思议。
  所以不论是在便携性上,还是在实用性上,大电池、长待机的智能手机都远比快充智能手机实用,就算是三星用光一次电池,并且找到地方充电,其最终使用时间,或许也并不如铂金版的时间长。
  二、使用频率增加,突然没电
  这应该属于意外情况,但在生活中也比较常见,特别是人士,遇到紧急事情需要处理的时候,发邮件、打,几个折腾现在智能手机就没电了,在办公室当然还好说,但是在外面呢?
  同样,携带移动电源是最无奈的方法,而如果选择具有快充功能的智能手机,例如三星S6,还是同样面临了寻找充电接口的问题,虽然大部分商务人士都可以通过酒店、办公室、咖啡厅等找到,但找到之后呢?难道告诉对方:“请您稍等,我充五分钟电之后再和您联系”吗?毕竟充电通话是多么危险的事情,更何况是在快充这样大功率的充电行为面前,更加危险。
  而对于大电池、超长待机的vivo X5Max,则几乎不会遇到这样的问题,且不说4150毫安的电池要打多少电话、发多少邮件才能用光,就算真的繁忙到用光了,那么直接调整到省电模式,就算还剩下1%的电,也足够讲几十分钟的电话了。相比之下,三星S6等品牌在快充方面所宣传的充电分钟就可以通话两小时的宣传就显得又麻烦,又无用了。
  三、忘记充电
  一般来说,这种情况比较少见,毕竟大家都用智能手机这么长时间了,一天一充的习惯也养成了,但毕竟还是有例外的,例如回去太累,直接睡了;例如喝醉了;例如玩着手机睡着了等等,到最终造成的结果都是第二天手机没电了。
  那么,在这样的情况下,移动电源几乎也解决不了问题。对于有快充的智能手机,就比较好办了,早上起来一看没电了,充个半小时,基本就能解决问题,再不济因为起晚了,充个五分钟,也能解决燃眉之急。
  而对于拥有4150毫安的vivo X5Max铂金版而言,就算忘记充电了,第二天也能撑一整天,任性就这么简单。所以在这样的情况下,不论是快充的三星S6或者是大电池的vivo X5Max铂金版,都可以解决问题。
  四、没电恐慌症
  不论是移动电源,还是快充智能手机,都治疗不了这个病症,但是4150毫安电池的vivo X5Max铂金版还是能缓解一些病情的,至少可以保证一两天不发病……
  好了,扯了这么多,总归还是因为电池的发展速度目前确实还处于瓶颈期,制约了整个智能手机的发展,虽然有了快速充电和大电池、长续航的智能手机,但其目的还是治标不治本。但在没有办法的情况下,选择类似与vivo X5Max铂金版这样拥有4150毫安的大电池、长续航智能手机,其实用性、便携性和安全性,都远远高于类似三星S6等机型的快速充电技术。应该是目前解决续航问题的首选。
(作者:佚名责任编辑:曾珊)
天极新媒体&最酷科技资讯扫码赢大奖
* 网友发言均非本站立场,本站不在评论栏推荐任何网店、经销商,谨防上当受骗!
主屏尺寸:5.5英寸
CPU型号:高通骁龙615(MSM8939)
4G制式:移动TD-LTE
处理器核心:八核
操作系统版本:Funtouch OS 2.0
RAM容量:2GB
ROM容量:16GB
电池容量(mAh):2000mAh
后置摄像头:1300万
前置摄像头:500万
网上商城商品/规格/促销价格
整机数码游戏软件常见的八种导致 APP 内存泄漏的问题 - 移动开发 - ITeye资讯
相关知识库:
本文来自:
像Java这样具有垃圾回收功能的语言的好处之一,就是程序员无需手动管理内存分配。这减少了段错误(segmentation fault)导致的闪退,也减少了内存泄漏导致的堆空间膨胀,让编写的代码更加安全。然而,Java 中依然有可能发生内存泄漏。所以你的安卓 APP 依然有可能浪费了大量的内存,甚至由于内存耗尽(OOM)导致闪退。
传统的内存泄漏是由忘记释放分配的内存导致的,而逻辑上的内存泄漏则是由于忘记在对象不再被使用的时候释放对其的引用导致的。如果一个对象仍然存在强引用,垃圾回收器就无法对其进行垃圾回收。在安卓平台,泄漏 Context 对象问题尤其严重。这是因为像 Activity 这样的 Context 对象会引用大量很占用内存的对象,例如 View 层级,以及其他的资源。如果 Context 对象发生了内存泄漏,那它引用的所有对象都被泄漏了。安卓设备大多内存有限,如果发生了大量这样的内存泄漏,那内存将很快耗尽。
如果一个对象的合理生命周期没有清晰的定义,那判断逻辑上的内存泄漏将是一个见仁见智的问题。幸运的是,activity 有清晰的生命周期定义,使得我们可以很明确地判断 activity 对象是否被内存泄漏。onDestroy() 函数将在 activity 被销毁时调用,无论是程序员主动销毁 activity,还是系统为了回收内存而将其销毁。如果 onDestroy 执行完毕之后,activity 对象仍被 heap root 强引用,那垃圾回收器就无法将其回收。所以我们可以把生命周期结束之后仍被引用的 activity 定义为被泄漏的 activity。
Activity 是非常重量级的对象,所以我们应该极力避免妨碍系统对其进行回收。然而有多种方式会让我们无意间就泄露了 activity 对象。我们把可能导致 activity 泄漏的情况分为两类,一类是使用了进程全局(process-global)的静态变量,无论 APP 处于什么状态,都会一直存在,它们持有了对 activity 的强引用进而导致内存泄漏,另一类是生命周期长于 activity 的线程,它们忘记释放对 activity 的强引用进而导致内存泄漏。下面我们就来详细分析一下这些可能导致 activity 泄漏的情况。
1.静态 Activity
泄漏 activity 最简单的方法就是在 activity 类中定义一个 static 变量,并且将其指向一个运行中的 activity 实例。如果在 activity 的生命周期结束之前,没有清除这个引用,那它就会泄漏了。这是因为 activity(例如 MainActivity) 的类对象是静态的,一旦加载,就会在 APP 运行时一直常驻内存,因此如果类对象不卸载,其静态成员就不会被垃圾回收。
void setStaticActivity() {
activity =
View saButton = findViewById(R.id.sa_button);
saButton.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
setStaticActivity();
nextActivity();
内存泄漏场景 1 - Static Activity
2. 静态 View
另一种类似的情况是对经常启动的 activity 实现一个单例模式,让其常驻内存可以使它能够快速恢复状态。然而,就像前文所述,不遵循系统定义的 activity 生命周期是非常危险的,也是没必要的,所以我们应该极力避免。
但是如果我们有一个创建起来非常耗时的 View,在同一个 activity 不同的生命周期中都保持不变呢?所以让我们为它实现一个单例模式,就像这段代码。现在一旦 activity 被销毁,那我们就应该释放大部分的内存了。
void setStaticView() {
view = findViewById(R.id.sv_button);
View svButton = findViewById(R.id.sv_button);
svButton.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
setStaticView();
nextActivity();
内存泄漏场景 2 - Static View
内存泄漏了!因为一旦 view 被加入到界面中,它就会持有 context 的强引用,也就是我们的 activity。由于我们通过一个静态成员引用了这个 view,所以我们也就引用了 activity,因此 activity 就发生了泄漏。所以一定不要把加载的 view 赋值给静态变量,如果你真的需要,那一定要确保在 activity 销毁之前将其从 view 层级中移除。
现在让我们在 activity 内部定义一个类,也就是内部类。这样做的原因有很多,比如增加封装性和可读性。如果我们创建了一个内部类的对象,并且通过静态变量持有了 activity 的引用,那也会发生 activity 泄漏。
void createInnerClass() {
class InnerClass {
inner = new InnerClass();
View icButton = findViewById(R.id.ic_button);
icButton.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
createInnerClass();
nextActivity();
内存泄漏场景 3 - Inner Class
不幸的是,内部类能够引用外部类的成员这一优势,就是通过持有外部类的引用来实现的,而这正是 activity 泄漏的原因。
类似的,匿名类同样会持有定义它们的对象的引用。因此如果在 activity 内定义了一个匿名的 AsyncTask 对象,就有可能发生内存泄漏了。如果 activity 被销毁之后 AsyncTask 仍然在执行,那就会组织垃圾回收器回收 activity 对象,进而导致内存泄漏,直到执行结束才能回收 activity。
void startAsyncTask() {
new AsyncTask&Void, Void, Void&() {
@Override protected Void doInBackground(Void... params) {
while(true);
}.execute();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View aicButton = findViewById(R.id.at_button);
aicButton.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
startAsyncTask();
nextActivity();
内存泄漏场景 4 - AsyncTask
5. Handlers
同样的,定义一个匿名的 Runnable 对象并将其提交到 Handler 上也可能导致 activity 泄漏。Runnable 对象间接地引用了定义它的 activity 对象,而它会被提交到 Handler 的 MessageQueue 中,如果它在 activity 销毁时还没有被处理,那就会导致 activity 泄漏了。
void createHandler() {
new Handler() {
@Override public void handleMessage(Message message) {
super.handleMessage(message);
}.postDelayed(new Runnable() {
@Override public void run() {
while(true);
}, Long.MAX_VALUE && 1);
View hButton = findViewById(R.id.h_button);
hButton.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
createHandler();
nextActivity();
内存泄漏场景 5 - Handler
6. Threads
同样的,使用Thread和TimerTask也可能导致activity泄漏。
void spawnThread() {
new Thread() {
@Override public void run() {
while(true);
}.start();
View tButton = findViewById(R.id.t_button);
tButton.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
spawnThread();
nextActivity();
内存泄漏场景 6 - Thread
7. Timer Tasks
只要它们是通过匿名类创建的,尽管它们在单独的线程被执行,它们也会持有对 activity 的强引用,进而导致内存泄漏。
void scheduleTimer() {
new Timer().schedule(new TimerTask() {
public void run() {
while(true);
}, Long.MAX_VALUE && 1);
View ttButton = findViewById(R.id.tt_button);
ttButton.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
scheduleTimer();
nextActivity();
内存泄漏场景 7 - TimerTask
8. Sensor Manager
最后,系统服务可以通过 context.getSystemService 获取,它们负责执行某些后台任务,或者为硬件访问提供接口。如果 context 对象想要在服务内部的事件发生时被通知,那就需要把自己注册到服务的监听器中。然而,这会让服务持有 activity 的引用,如果程序员忘记在 activity 销毁时取消注册,那就会导致 activity 泄漏了。
void registerListener() {
SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ALL);
sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_FASTEST);
View smButton = findViewById(R.id.sm_button);
smButton.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
registerListener();
nextActivity();
内存泄漏场景 8 - Sensor Manager
现在,我们展示了八种很容易不经意间就泄漏大量内存的情景。请记住,最坏的情况下,你的 APP 可能会由于大量的内存泄漏而内存耗尽,进而闪退,但它并不总是这样。相反,内存泄漏会消耗大量的内存,但却不至于内存耗尽,这时,APP 会由于内存不够分配而频繁进行垃圾回收。垃圾回收是非常耗时的操作,会导致严重的卡顿。在 activity 内部创建对象时,一定要格外小心,并且要经常测试是否存在内存泄漏。Android内存优化-内存泄漏的几个场景以及解决方式-学网-中国IT综合门户网站-提供健康,养生,留学,移民,创业,汽车等信息
Android内存优化-内存泄漏的几个场景以及解决方式
来源:互联网 更新时间: 14:57:56 责任编辑:王亮字体:
解决了Handler隐式持有外部类Activity引用,Runnable在之前的代码中作为匿名内部类隐式持有Handler引用,所以我们在Activity内部定义一个静态变量引用Runnable类,这是因为匿名类的静态实例不会隐式持有他们外部类的引用。
public class MainActivity extends AppCompatActivity {
private final MyHandler mHandler = new MyHandler(this);
private static Runnable sRunnable = new Runnable() {
public void run() {
我们也可以这样做:&在Activity的onDestroy方法中干掉handler中所有的callback和message:
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacksAndMessages(null);
2.非静态匿名内部类造成内存泄漏
在中最常见的操作就是当有耗时操作的时候我们不能在主线程执行这些操作,否则有可能造成ANR,主线程主要是UI操作的主战场。&比如网络请求或者查询这些耗时操作我们需要自己另外开启线程,在子线程中执行这些耗时操作。当我们需要开启的子线程比较少的时候,直接new Thread(Runnable)就可以了。如果你经常这样做的话就说明你没有注意到有可能会产生内存泄漏的问题。&
相关文章:
上一篇文章:下一篇文章:
最新添加资讯
24小时热门资讯
Copyright © 2004- All Rights Reserved. 学网 版权所有
京ICP备号-1 京公网安备02号

我要回帖

更多关于 内存泄漏怎么解决 的文章

 

随机推荐