Я часто слышу, что «удержание статической активности или представления, особенно внутри AsyncTask, которая долго работает, приведет к утечке памяти и падению вашего приложения».
Это упрощенное объяснение.
Однако мне не удалось доказать это в эмуляторе Android.
Я подозреваю, что этот код не работает.Вы должны аварийно завершить работу после нескольких сотен проходов через цикл, поскольку существует ограничение на количество AsyncTasks
в очереди, которое вы можете иметь, и это ограничение не связано с потреблением памяти.
Игнорирование миллионаAsyncTasks
и миллион ImageViews
, вы пропускаете активность с помощью sHolder
, так же, как в этом примере я пропускаю активность, удерживая static
ссылку на Button
в ее макете:
/***
Copyright (c) 2015 CommonsWare, LLC
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
by applicable law or agreed to in writing, software distributed under the
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
Covered in detail in the book _The Busy Coder's Guide to Android Development_
https://commonsware.com/Android
*/
package com.commonsware.android.button;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
public class ButtonDemoActivity extends Activity {
private static Button pleaseDoNotDoThis;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pleaseDoNotDoThis=(Button)findViewById(R.id.button1);
}
}
Вы можете продемонстрировать, что утечка происходит, используя LeakCanary, анализатор кучи Android Studio и т. Д. Однако, чтобы продемонстрировать эту утечку, вам нужно запустить приложение, затем нажать НАЗАД и увидеть, что ваша уничтоженная активность несборщиком мусора.Либо вам нужно запустить приложение, повернуть экран (или изменить конфигурацию любого другого типа) и увидеть, что теперь у вас есть два экземпляра активности: разрушенный и с утечкой и текущий.Если вы просто запускаете приложение и ничего не делаете, у вас нет утечки активности - хотя у вас есть собственная статическая ссылка на нее, то же самое происходит и с Android, потому что активность находится на переднем плане, и пользователь может ее видеть.
Утечка сама по себе не вызывает сбой.Это просто означает, что вы связываете кучу пространства, которое нельзя использовать для других целей.В конце концов, вы получите OutOfMemoryError
на некоторое распределение.Если все, что вы хотите сделать, это аварийно завершить работу с OutOfMemoryError
, попробуйте выделить несколько крупных byte[]
(скажем, 1 ГБ).
Если вы специально хотите протестировать OutOfMemoryError
, вызванный утечкой активности, вы бынеобходимо:
Чтобы действие выделило значительный объем пространства кучи (например, 1 МБ byte[]
),
Сделайте что-то вродеваш список sHolder
и
Поверните экран сильно или иным образом поставьте себя в ситуацию, когда множество экземпляров действия будут созданы и уничтожены, но не собраны мусоромЛюбезно предоставлено sHolder