为什么堆内存增加时,重新启动一个活动? [英] Why does heap memory increase when re-launching an activity?

查看:126
本文介绍了为什么堆内存增加时,重新启动一个活动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题在Android中涉及到内存中。

我的方法:

我有两个运动,A和B.从A,我发起b类似这样的:

 意向书我=新的意图(A.this,B.class);
startActivity(ⅰ);
 

在单击按钮在B,我这样做:

  B.this.finish();
 

  • 在B,我重写的onDestroy方法和设置的所有引用为null。
  • 在我不在A的onResume方法分配新的内存
  • 在我没有泄露上下文。
  • 在我没有使用多个线程。
  • 在我没有使用的服务。
  • 在B全变量都是私有类变量,所有这些都必须在B的的onDestroy设置为null
  • 此外,B中ImageViews已经在B的的onDestroy他们的背景设置为空值
  • 我敢肯定,B会得到破坏。

结果:

当我在活动A,堆内存为7.44 MB。后来,当我开始B和呼叫完成对B(并因此回归A),堆增加0.16 MB。再次重复这个过程中,堆增加0.08 MB每一次。

  • 在我不看堆限制,我期待在堆分配。
  • 在我调用System.gc()在B的的onDestroy方法的末尾。

附加信息:

- 我已经使用MAT分析内存分配,并设法找到此泄漏。一些奇怪的是,b活动似乎有5个实例。由于恰巧,我重复startActivity /精细加工工艺的5倍。底部项是活动,其他人都在活动监听器:

这是支配树的截图。我找不到任何不寻常或可疑的。

- 我看过这两个谷歌IO视频内存的使用(和泄漏)。

问:

难道这0.08 MB堆总是会不管我做什么分配(而不是由GC收藏)?如果不是,什么可能会导致此任何想法?

更新:

  1. 我试图推出b活动没有设置在B的内容视图这意味着,B是一个完全空白的活动。其结果是,堆内存也当我重新发起活动几次没有增加。但是请注意,这是没有办法了。我必须能够设置一个内容视图。

  2. scorpiodawg:我想在一个模拟器上运行我的应用程序,并且堆仍然增长。很好的尝试,但。

  3. NTC:我改变了这个为getApplicationContext()里,有可能所有的实例。我不能打电话的setContentView(getApplicationContext());因为的setContentView想引用一个布局文件,而不是一个方面。我所做的,而不是是创建一个空的布局文件和调用的setContentView(emptylayout);在活动B.没有帮助的的onDestroy方法。

  4. 我试图删除所有code,以便只的setContentView(mylayout)被调用。问题依然存在。然后,我删除了布局XML文件中的所有GUI元素。问题依然存在。所以,剩下的唯一的事情就是容器的观点,一对夫妇的嵌套线性的,相对的,scrolllayouts。我试图删除设置了机器人:scrollbarDefaultDelayBeforeFade属性中的滚动条。其结果是伟大的,内存泄漏消失了。然后我放回所有code我previously删除,但没有设置机器人:scrollbarDefaultDelayBeforeFade属性和内存泄漏又回来了。多么奇怪的是?

解决方案

如果您有活性的B 5个实例,那么你就不能正确地管理活动栈。 我觉得要检查它与CLI命令的最佳方式:

亚行外壳dumpsys meminfo中您的应用程序包名称

我在两个活动项目也有类似的问题,当我打开他们之间。每次我换我在堆栈上一个新的实例所揭示的上述命令。我然后设置标志启动的活动FLAG_ACTIVITY_REORDER_TO_FRONT与code这样的:

 意向书我=新的意向书(com.you.yourActivityB);
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(ⅰ);
 

一旦我做到了这一点,那么亚行的shell命令没有显示我的两个活动的多个实例,当我打开他们的

This question concerns memory in Android.

My method:

I have two activites, A and B. From A, I launch B like this:

Intent i = new Intent(A.this, B.class);
startActivity(i);

On button click in B, I do this:

B.this.finish();

  • In B, I override the onDestroy method and set all references to null.
  • I do not allocate new memory in the onResume method of A.
  • I am not leaking a context.
  • I am not using multiple threads.
  • I am not using services.
  • All variables in B are private class variables, and all of them are set to null in the onDestroy of B.
  • Also, ImageViews in B have their background set null in the onDestroy of B.
  • I am certain that B gets destroyed.

The result:

When I am in Activity A, heap memory is at 7.44 MB. Then when I start B and call finish on B(and thus returning to A), heap is increased by 0.16 MB. Repeating this process again, heap is increased by 0.08 MB every time.

  • I'm not looking at the heap limit, I'm looking at the allocated heap.
  • I'm calling System.gc() at the end of the onDestroy method of B.

Additional info:

-I have used MAT to analyse memory allocations and try to find this leak. Something strange is that Activity B seems to have 5 instances. As it so happens, I was repeating the startActivity/finish process 5 times. The bottom entry is the Activity, the others are listeners in the activity:

And this is screenshot of the dominator tree. I can't find anything unusual or suspect.

-I have watched both google IO videos on memory usage(and leaks).

Question:

Is it possible that this 0.08 MB of heap will always be allocated(and not collectable by the GC) no matter what I do? If not, any idea of what might be causing this?

Update:

  1. I tried to launch activity B without setting a content view in B. This means that B is a completely empty activity. The result was that the heap memory did NOT increase when I'm relaunching the activity several times. Note, however, that this is no solution. I must be able to set a content view.

  2. scorpiodawg: I tried running my app on an emulator, and the heap still grows. Good try though.

  3. ntc: I changed all occurences of "this" to "getApplicationContext()" where it was possible. I could not call setContentView(getApplicationContext()); because setContentView wants a reference to a layout file, not a context. What I did instead was to create an empty layout file and call setContentView(emptylayout); in the onDestroy method of Activity B. That did not help.

  4. I tried to remove all the code so that only setContentView(mylayout) gets called. Problem persisted. Then I removed all the gui elements in the layout XML file. Problem persisted. The only thing that was left was the container views, a couple of nested linear, relative and scrolllayouts. I tried to remove setting the "android:scrollbarDefaultDelayBeforeFade" attribute in the scrollbar. The result was great, the memory leak had vanished. Then I put back all the code I previously removed but didn't set the "android:scrollbarDefaultDelayBeforeFade" attribute and the memory leak was back. How strange is that?

解决方案

If you have 5 instances of activity B, then you are not managing the activity stack correctly. I find the best way to check it is with the CLI command:

adb shell dumpsys meminfo 'your apps package name'

I had a similar problem in a two activity project when I switched between them. Every time I switched I got a new instance on the stack as revealed by the above command. I then set the flags for the launched activities to FLAG_ACTIVITY_REORDER_TO_FRONT with code like:

Intent i = new Intent("com.you.yourActivityB");
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(i);

Once I'd done this, then the adb shell command did not show more instances of my two activities when I switched between them

这篇关于为什么堆内存增加时,重新启动一个活动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆