Die Gründe und Lösungen sind: 1. Verwenden Sie statische interne Klassen, um durch Threads verursachte Speicherverluste zu vermeiden. 2. Verwenden Sie die zwischengespeicherte ConvertView, um durch ListView verursachte Speicherverluste zu vermeiden. 3. Löschen Sie den Inhalt der Sammlung, bevor Sie das Programm beenden , auf null setzen, um Speicherverluste im Sammelcontainer zu vermeiden.
Die Betriebsumgebung dieses Tutorials: Windows 7-System, Dell G3-Computer.
1. Speicherlecks durch Singletons
Aufgrund der statischen Natur des Singletons ist sein Lebenszyklus so lang wie der Lebenszyklus der Anwendung nicht mehr Es muss verwendet werden, aber das Singleton-Objekt enthält weiterhin einen Verweis auf das Objekt, wodurch verhindert wird, dass das Objekt normal recycelt wird, was zu einem Speicherverlust führt.
Beispiel: Verhindern Sie, dass Singleton-Instanzen Speicherverluste verursachen.
// 使用了单例模式 public class AppManager { private static AppManager instance; private Context context; private AppManager(Context context) { this.context = context; } public static AppManager getInstance(Context context) { if (instance != null) { instance = new AppManager(context); } return instance; } }
2. Speicherverluste, die durch die Erstellung statischer Instanzen nicht statischer innerer Klassen verursacht werden Dieselbe Datenressource kann wie folgt geschrieben werden:
public class MainActivity extends AppCompatActivity { private static TestResource mResource = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if(mResource == null){ mResource = new TestResource(); } //... } class TestResource { //... } }
3. Speicherverlust durch Handler
Beispiel: Erstellen Sie ein statisches Objekt einer anonymen inneren Klasse
public class MainActivity extends AppCompatActivity { private final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { // ... } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Thread(new Runnable() { @Override public void run() { // ... handler.sendEmptyMessage(0x123); } }); } }
4. Durch Threads verursachte Speicherlecks
Beispiel: AsyncTask und Runnable
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Thread(new MyRunnable()).start(); new MyAsyncTask(this).execute(); } class MyAsyncTask extends AsyncTask<Void, Void, Void> { // ... public MyAsyncTask(Context context) { // ... } @Override protected Void doInBackground(Void... params) { // ... return null; } @Override protected void onPostExecute(Void aVoid) { // ... } } class MyRunnable implements Runnable { @Override public void run() { // ... } } }
5. Durch nicht geschlossene Ressourcen verursachte Speicherlecks
Für Ressourcen wie BroadcastReceiver, ContentObserver, Datei, Cursor, Stream, Bitmap usw. sollten diese rechtzeitig geschlossen oder abgemeldet werden, wenn die Aktivität zerstört wird Ressourcen werden nicht recycelt, was zu einem Speicherverlust führt.
1) Beispielsweise ist ein BraodcastReceiver in der Aktivität registriert, die Registrierung des BraodcastReceiver wird jedoch nach Ende der Aktivität nicht aufgehoben. 2) Ressourcenobjekte wie Cursor, Stream, Datei usw. verwenden häufig einige Puffer. Wenn wir sie nicht verwenden, sollten wir sie rechtzeitig schließen, damit ihre Puffer rechtzeitig Speicher zurückgewinnen können. Ihre Puffer existieren nicht nur innerhalb der Java Virtual Machine, sondern auch außerhalb der Java Virtual Machine. Wenn wir die Referenzen einfach auf null setzen, ohne sie zu schließen, kommt es häufig zu Speicherverlusten. 3) Wenn ein Ressourcenobjekt nicht verwendet wird, sollte seine Funktion close() aufgerufen werden, um es zu schließen, und dann auf null gesetzt werden. Wir müssen sicherstellen, dass unsere Ressourcenobjekte geschlossen sind, wenn unser Programm beendet wird. 4) Rufen Sie recycle() auf, um Speicher freizugeben, wenn das Bitmap-Objekt nicht mehr verwendet wird. Bitmaps nach 2.3 sollten nicht mehr manuell recycelt werden müssen, da sich der Speicher bereits in der Java-Ebene befindet.6. Speicherlecks bei Verwendung von ListView
ListView instanziiert zunächst eine bestimmte Anzahl von View-Objekten von BaseAdapter basierend auf dem aktuellen Bildschirmlayout und ListView speichert diese View-Objekte zwischen. Wenn die ListView nach oben gescrollt wird, wird das View-Objekt des ursprünglich oben befindlichen Elements wiederverwendet und dann zum Erstellen des darunter angezeigten Elements verwendet. Dieser Konstruktionsprozess wird durch die Methode getView() abgeschlossen. Der zweite formale Parameter ConvertView von getView() ist das View-Objekt des zwischengespeicherten Elements (wenn während der Initialisierung kein View-Objekt im Cache vorhanden ist, ist ConvertView null).
Beim Erstellen des Adapters wird die zwischengespeicherte ConvertView nicht verwendet. Lösung: Verwenden Sie beim Erstellen des Adapters die zwischengespeicherte ConvertView.7. Speicherleck im Sammelbehälter
Normalerweise fügen wir einige Objektreferenzen zu einem Sammlungscontainer hinzu (z. B. ArrayList). Wenn wir das Objekt nicht mehr benötigen, löschen wir seine Referenzen nicht aus der Sammlung, sodass die Sammlung immer größer wird. Wenn diese Sammlung statisch ist, ist die Situation noch ernster.
Lösung: Löschen Sie vor dem Beenden des Programms die Elemente in der Sammlung, setzen Sie sie dann auf Null und beenden Sie dann das Programm.
8. Durch WebView verursachter Verlust
Wenn wir das WebView-Objekt nicht verwenden, sollten wir seine Funktion destroy() aufrufen, um es zu zerstören und den Speicher freizugeben, den es für lange Zeit belegt hat kann nicht recycelt werden. Dies führt zu einem Speicherverlust.
Lösung: Öffnen Sie einen anderen Prozess für WebView und kommunizieren Sie über AIDL mit dem Hauptthread. Der Prozess, in dem sich WebView befindet, kann den geeigneten Zeitpunkt für die Zerstörung entsprechend den Geschäftsanforderungen auswählen und so eine vollständige Speicherfreigabe erreichen.
Für mehr Computerwissen besuchen Sie bitte die FAQ-Kolumne!
Das obige ist der detaillierte Inhalt vonWas sind die Ursachen und Lösungen für Speicherlecks?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!