Утечки памяти в приложении для Android

Я испытываю некоторые утечки памяти в своем приложении. В первый раз, когда я подозревал, что утечка памяти была, когда я стресс-тестирование моего приложения, нажав кнопку, чтобы начать новую Activity . После использования DDMS и .hprof file , этот файл я открыл с помощью Eclipse Memory Analyzer

У меня есть три возможных утечки памяти, показанные на круговой диаграмме: Введите описание изображения здесь

И описание утечек памяти:

Подозреваемый 1

122 экземпляра «android.widget.LinearLayout», загруженные «», занимают 29 585 384 (38,74%) байт.

Самые большие экземпляры:

 •android.widget.LinearLayout @ 0x4258c008 - 2 268 848 (2,97%) bytes. •android.widget.LinearLayout @ 0x425c8688 - 2 268 848 (2,97%) bytes. •android.widget.LinearLayout @ 0x425e3988 - 2 268 848 (2,97%) bytes. •android.widget.LinearLayout @ 0x4296e198 - 2 268 848 (2,97%) bytes. •android.widget.LinearLayout @ 0x429d3aa8 - 2 268 848 (2,97%) bytes. •android.widget.LinearLayout @ 0x42a10c78 - 2 268 848 (2,97%) bytes. •android.widget.LinearLayout @ 0x448a1f10 - 2 268 848 (2,97%) bytes. •android.widget.LinearLayout @ 0x44a65d58 - 2 268 848 (2,97%) bytes. •android.widget.LinearLayout @ 0x42a14098 - 2 268 824 (2,97%) bytes. •android.widget.LinearLayout @ 0x4258bd30 - 999 528 (1,31%) bytes. •android.widget.LinearLayout @ 0x425c83b0 - 999 528 (1,31%) bytes. •android.widget.LinearLayout @ 0x425ddff8 - 999 528 (1,31%) bytes. •android.widget.LinearLayout @ 0x4296df80 - 999 528 (1,31%) bytes. •android.widget.LinearLayout @ 0x42a109a0 - 999 528 (1,31%) bytes. •android.widget.LinearLayout @ 0x42a13dc0 - 999 528 (1,31%) bytes. •android.widget.LinearLayout @ 0x448a1c38 - 999 528 (1,31%) bytes. •android.widget.LinearLayout @ 0x448cc338 - 999 528 (1,31%) bytes. •android.widget.LinearLayout @ 0x44a65a80 - 999 528 (1,31%) bytes. 

Подозреваемый 2

15 экземпляров «android.widget.FrameLayout», загруженные «», занимают 29 405 016 (38,51%) байтов.

Самые большие экземпляры:

 •android.widget.FrameLayout @ 0x4245b490 - 3 266 728 (4,28%) bytes. •android.widget.FrameLayout @ 0x4247a330 - 3 266 728 (4,28%) bytes. •android.widget.FrameLayout @ 0x425aa1d8 - 3 266 728 (4,28%) bytes. •android.widget.FrameLayout @ 0x425df8b0 - 3 266 728 (4,28%) bytes. •android.widget.FrameLayout @ 0x425efe68 - 3 266 728 (4,28%) bytes. •android.widget.FrameLayout @ 0x42627590 - 3 266 728 (4,28%) bytes. •android.widget.FrameLayout @ 0x42987a70 - 3 266 728 (4,28%) bytes. •android.widget.FrameLayout @ 0x4299df20 - 3 266 728 (4,28%) bytes. •android.widget.FrameLayout @ 0x448b6f28 - 3 266 728 (4,28%) bytes. 

Подозреваемый 3

 2 682 instances of "java.lang.Class", loaded by "<system class loader>" occupy 8 662 744 (11,34%) bytes. Biggest instances: •class android.content.res.Resources @ 0x41a4f708 - 7 485 176 (9,80%) bytes. 

Моя первая мысль заключалась в том, чтобы посмотреть в файл R.java , потому что я мог видеть некоторые шестнадцатеричные ссылки на возможную утечку памяти. Я попытался выполнить поиск после шестнадцатеричной строки из Eclipse Memory Analyzer, но я не смог найти адреса в файле R.java .

Затем я посмотрел в Дерево Доминатора, и это результат: Введите описание изображения здесь

Это только первая запись в списке, но это самый большой.

С этой информацией, может кто-нибудь дать мне подсказку о том, как я могу отслеживать утечку памяти? Добавьте комментарий, если мне нужно добавить дополнительную информацию к этому сообщению.

Заранее спасибо.

РЕДАКТИРОВАТЬ

Проблема может быть в моем базовом классе. Все действия наследуются от этого класса. Эта задача состоит в том, чтобы установить SlidingMenu в левом верхнем углу. Это код для этого класса:

  public class Base extends Activity implements OnSlideMenuItemClickListener { public SlideMenu slidemenu; ImageButton b; Time t; BluetoothCommunicator btCom; BroadcastReceiver btBroadCaster; MonitorBluetoothState bluetoothState; public void setTab(int id) { setContentView(id); overridePendingTransition(R.anim.activityfade, R.anim.activityfadeout); slidemenu = (SlideMenu) findViewById(R.id.slideMenu); slidemenu.init(this, R.menu.slide, this, 450); slidemenu.setHeaderImage(getResources().getDrawable(R.drawable.ic_launcher)); b = (ImageButton) findViewById(R.id.BtnSlide); b.setOnClickListener(new OnClickListener() { public void onClick(View v) { slidemenu.show(); } }); b.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: b.setImageResource(R.drawable.lincolor); break; case MotionEvent.ACTION_UP: b.setImageResource(R.drawable.lin); break; } return false; } }); } @Override public void onSlideMenuItemClick(int itemId) { Class<?> cls = null; switch(itemId) { case R.id.item_one: cls = Home.class; break; case R.id.item_two: cls = History.class; break; case R.id.item_three: cls = ClearHistoryDialog.class; break; case R.id.item_four: cls = SendLogDialog.class; break; case R.id.item_five: cls = PasswordDialog.class; break; case R.id.item_six: cls = About.class; break; } Intent intent = new Intent(this, cls); startActivity(intent); } } 

В других моих действиях этот метод setTab будет вызываться следующим образом:

  public class Main extends Base { public void onCreate(Bundle b) { super.onCreate(b); super.setTab(R.layout.Home); } } 

Если макет Home выглядит следующим образом:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/parent" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#e4e8ed" android:gravity="top" > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/first" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="0px" > <include android:id="@+id/tabBar" layout="@layout/tab" /> <com.workspace.tobias android:id="@+id/slideMenu" android:layout_width="match_parent" android:layout_height="match_parent" /> <Button android:id="@+id/nist" android:layout_width="match_parent" android:layout_height="67dp" android:layout_gravity="center_horizontal" android:layout_marginBottom="3dp" android:layout_marginLeft="3dp" android:layout_marginRight="3dp" android:layout_marginTop="3dp" android:background="@drawable/ready" android:textColor="#FFFFFF" /> <ListView android:id="@+id/lastCases" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/loading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginTop="300dp" android:orientation="horizontal" > <ProgressBar android:id="@+id/progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:indeterminate="true" /> <TextView android:id="@+id/loadingCases" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:text="@string/Loading" android:textColor="#707070" android:textSize="18dp" android:layout_marginLeft="10dp" /> </LinearLayout> </RelativeLayout> 

Используете ли вы статические переменные для кэширования больших ресурсов?
Если да, то в приложениях Android распространять ошибку, чтобы использовать контекст активности для загрузки таких ресурсов. Это приводит к поддержанию активности и всех их ресурсов, хотя они больше не нужны.
Чтобы исправить это, используйте контекст приложения для загрузки таких ресурсов!

Вы можете обратиться к этому блогу блога разработчиков Android для более подробной информации.