为什么堆内存增加时,重新启动一个活动?重新启动、内存

2023-09-03 22:33:32 作者:夏沫べ夜微凉

这个问题在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收藏)?如果不是,什么可能会导致此任何想法?

更新:

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

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

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

我试图删除所有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:

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.

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

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.

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