45 Techniken zur Optimierung der Java-Leistung (Teil 1)

Vorwort: Da Japanisch nicht muttersprachlich ist, gibt es meiner Meinung nach einige seltsame Ausdrücke und falsche Grammatiken. Ich würde es begrüßen, wenn Sie darauf hinweisen könnten.

In JAVA-Programmen liegen die meisten Leistungsprobleme nicht in der JAVA-Sprache, sondern im Programm selbst. Es ist wichtig, gute Codierungsgewohnheiten zu entwickeln, die die Leistung Ihres Programms erheblich verbessern können.

1. Stellen Sie sicher, dass Sie Singleton an der richtigen Stelle verwenden

Die Verwendung einzelner Tonnen reduziert die Last, verkürzt die Ladezeiten und verbessert die Ladeeffizienz. Nicht alle Standorte sind jedoch für einzelne Tonnen geeignet.

Einfach ausgedrückt kann Singleton auf drei Hauptsituationen angewendet werden:

  1. Steuern Sie die Ressourcennutzung und den gleichzeitigen Ressourcenzugriff durch Thread-Synchronisation.
  2. Steuern Sie die Generierung von Instanzen, um den Zweck des Ressourcenschutzes zu erreichen.
  3. Sie möchten die gemeinsame Nutzung von Daten steuern und die Kommunikation zwischen mehreren nicht verwandten Prozessen oder Threads ermöglichen, ohne eine direkte Zuordnung herzustellen.

2. Verwenden Sie statische Variablen nicht frei

Wenn ein Objekt als statische Variable definiert ist, stellt GC den von diesem Objekt belegten Speicher normalerweise nicht wieder her.

public class A {
  private static B b = new B();
}

Zu diesem Zeitpunkt ist der Lebenszyklus der statischen Variablen b mit der Klasse A synchronisiert. Wenn die Klasse A nicht entladen wird, bleibt das Objekt b im Speicher, bis das Programm beendet wird.

3. Erstellen Sie nicht zu viele Java-Objekte

Das System benötigt nicht nur viel Zeit zum Erstellen von Objekten, sondern auch viel Zeit zum Sammeln und Verarbeiten dieser Objekte. Vermeiden Sie daher das Erstellen neuer Objekte in häufig als Schleifen und Methoden bezeichneten Methoden. .. Es ist am besten, das Objekt durch einen grundlegenden Datentyp oder ein Array zu ersetzen.

4. Versuchen Sie es mit dem letzten Modifikator

Klassen mit dem endgültigen Modifikator können nicht abgeleitet werden. Es gibt viele Beispiele für Java-Kern-APIs mit Finals wie java.lang.String. Wenn Sie beispielsweise final in der String-Klasse angeben, kann der Benutzer die length () -Methode nicht überschreiben. Wenn die Klasse endgültig ist, sind außerdem alle Methoden in dieser Klasse endgültig. Der Java-Compiler sucht nach Möglichkeiten, alle endgültigen Methoden zu integrieren (dies ist für die Implementierung eines bestimmten Compilers relevant). Dies verbessert die Leistung um durchschnittlich 50%.

5. Verwenden Sie so viele lokale Variablen wie möglich

Wenn die Methode aufgerufen wird, können die übergebenen Parameter und die durch den Aufruf erstellten temporären Variablen schneller auf dem Stapel gespeichert werden. Andererseits werden andere Variablen wie statische Variablen und Instanzvariablen im Heap erstellt und sind langsamer als der Stapel.

6. Versuchen Sie, sowohl mit Box- als auch mit primitiven Typen umzugehen

Box- und Primitivtypen können während des Gebrauchs ineinander umgewandelt werden. Die von beiden erzeugten Speicherbereiche sind jedoch völlig unterschiedlich. Die Erzeugung und Verarbeitung primitiver Typen wird auf dem Stapel verarbeitet. Da Box-Typen Objekte sind, werden sie im Heap instanziiert. Die Verwendung primitiver Typen wird empfohlen, außer in Situationen, in denen eine Verarbeitung vom Typ Box erforderlich ist, z. B. in Sammlungen.

7. Minimieren Sie die Synchronisation

Wie wir alle wissen, ist die Synchronisierung ein großer Systemaufwand und kann sogar zu Deadlocks führen. Vermeiden Sie daher unnötige Synchronisierungssteuerungen. Wenn die Synchronisierungsmethode aufgerufen wird, wird das aktuelle Objekt direkt gesperrt, und kein anderer Thread kann andere Methoden des aktuellen Objekts aufrufen, bis die Methode abgeschlossen ist. Daher wird die Synchronisationsmethode minimiert und die Methodensynchronisation sollte anstelle der Codeblock-Synchronisation verwendet werden.

8. Verwenden Sie nicht die Finalisierungsmethode

Die GC-Arbeitslast ist so hoch, dass die Anwendung angehalten wird, insbesondere wenn der Young-Speicher recycelt wird. Wenn Sie also zu diesem Zeitpunkt die Finalize-Methode zum Bereinigen von Ressourcen verwenden, wird der GC überlastet und die Programmvorgänge sind langsam. Werden.

9. Versuchen Sie, anstelle von Objekten grundlegende Datentypen zu verwenden

String str = "hello";

Der obige Code erstellt eine "Hallo" -String, und der Zeichen-Cache-Pool der JVM speichert diesen String ebenfalls im Cache.

String str = new String("hello");

Zu diesem Zeitpunkt enthält das von str referenzierte String-Objekt neben dem Erstellen eines Strings auch ein char [] -Array. Dieses Array enthält h, e, l, l, o.

10. Verwenden Sie für Multithreading nach Möglichkeit HashMap und ArrayList, wenn Sie die Thread-Sicherheit nicht berücksichtigen müssen

HashTable, Vector usw. verwenden einen Synchronisationsmechanismus, der die Leistung verringert.

11. Erstellen Sie eine HashMap, die so rational wie möglich ist

Wenn Sie eine große HashMap erstellen möchten, geben Sie die Kapazität und den Auslastungsfaktor im Konstruktor unten so weit wie möglich an.

public HashMap(int initialCapacity, float loadFactor);

Vermeiden Sie die Erweiterung von HashMap. Die Erweiterung ist sehr kostspielig.

Standardmäßig beträgt die anfängliche Kapazität 16 und der loadFactor 0,75. Es ist jedoch wichtig, genau zu schätzen, wie viel Speicherplatz Sie benötigen und welche Größe Sie optimal benötigen. Gleiches gilt für Hashtable und Vektoren.

12. Reduzieren Sie die doppelte Berechnung von Variablen

for(int i=0;i<list.size();i++)

Im Falle von

for(int i=0,len=list.size();i<len;i++)

Muss geändert werden auf.

Verwenden Sie keine komplexen Ausdrücke in Schleifen. In Schleifen werden Schleifenbedingungen iterativ berechnet. Wenn Sie den Wert der Schleifenbedingung nicht ändern, ohne komplexe Ausdrücke zu verwenden, wird das Programm schneller ausgeführt.

13. Versuchen Sie, unnötige Instanziierungen zu vermeiden

Zum Beispiel:

A a = new A();

if(i==1){

  list.add(a);

}

Im Falle von,

if(i==1){

  A a = new A();

  list.add(a);

}

Sollte geändert werden zu.

14. Endlich Ressourcen mit Blöcken freigeben

Die vom Programm verwendeten Ressourcen sollten freigegeben werden, um Ressourcenlecks zu vermeiden. Dies geschieht am besten in einem Endblock. Unabhängig vom Ergebnis der Programmausführung werden schließlich immer Blöcke ausgeführt, um einen ordnungsgemäßen Ressourcenabschluss sicherzustellen.

15. Verwenden wir die Schaltoperation anstelle von 'a / b'.

Das "/" ist eine sehr teure Operation und ist bei Schichtoperationen schneller und effizienter. Zum Beispiel

int num = a / 4;

int num = a / 8;

Im Falle von,

int num = a >> 2;

int num = a >> 3;

Sollte geändert werden zu. Die Schichtoperation ist jedoch intuitiv und schwer zu verstehen. Daher ist es besser, Kommentare hinzuzufügen, wenn Sie die Schicht verwenden.

16. Verwenden wir die Schaltoperation anstelle von 'a * b'.

In ähnlicher Weise ist es für '*' Operationen schneller und effizienter, Schichtoperationen zu verwenden.

Zum Beispiel

int num = a * 4;

int num = a * 8;

Im Falle von,

int num = a << 2;

int num = a << 3;

Sollte geändert werden zu.

17. Die Kapazität von StringBuffer sollte so weit wie möglich im Voraus festgelegt werden.

Der StringBuffer-Konstruktor erstellt ein Array von Zeichen mit Standardgröße (normalerweise 16). Wenn diese Größe während der Verwendung überschritten wird, wird der Speicher neu zugewiesen, ein größeres Array wird erstellt, das ursprüngliche Array wird kopiert und das alte Array wird verworfen.

In den meisten Fällen können Sie die Größe beim Erstellen des StringBuffers angeben. Auf diese Weise können Sie eine automatische Erweiterung vermeiden, die auftritt, wenn nicht genügend Kapazität vorhanden ist, und die Leistung verbessern.

18. Geben Sie so schnell wie möglich Verweise auf nutzlose Objekte frei

In den meisten Fällen muss das Programm die Referenzvariable nicht explizit auf null setzen, da das Objekt, auf das die lokale Referenzvariable der Methode verweist, am Ende der Methode in den Papierkorb verschoben wird.

Zum Beispiel

Public void test(){

Object obj = new Object();

……

obj=null;

}

Im obigen Code müssen Sie ´obj = null´ nicht explizit ausführen.

Der Verweis auf obj wird freigegeben, wenn die Ausführung von method test () abgeschlossen ist.

Aber wenn das Programm wie folgt geändert wird:

public void test(){

Object obj = new Object();

// ……

Obj=null;

//Es werden zeitaufwändige, speicherintensive Operationen oder zeitaufwändige speicherintensive Methoden aufgerufen

// ……

}

Zu diesem Zeitpunkt kann durch explizites Zuweisen von null zu obj der Verweis auf Object frühzeitig freigegeben werden.

19. Vermeiden Sie so oft wie möglich zweidimensionale Arrays

Zweidimensionale Daten belegen viel mehr Speicherplatz als ein eindimensionales Array. Es ist ungefähr 10 mal.

20. Verwenden Sie Split nicht

Da Split reguläre Ausdrücke unterstützt, ist es relativ ineffizient und verbraucht viele Ressourcen. Erwägen Sie die Verwendung von StringUtils.split (string, char) von Apache, das häufig zwischengespeichert werden kann.

21. ArrayList und LinkedList

Eine ist eine lineare Tabelle, eine ist eine verknüpfte Liste, und abschließend ist ArrayList besser als LinkedList, wenn Sie get häufig aufrufen. Für LinkedList müssen Sie nacheinander scannen. Wenn Sie dagegen häufig Add oder Remove aufrufen, ist LinkedList besser als ArrayList. ArrayList muss Daten verschieben.

Dies ist eine theoretische Analyse. Verstehen Sie die Datenstruktur von beiden und ergreifen Sie je nach Situation geeignete Maßnahmen.

22. Verwenden Sie System.arraycopy (), anstatt ein Array zu schleifen und zu kopieren

System.arraycopy () ist viel schneller als das Schleifen und Kopieren eines Arrays.

23. Cache häufig verwendeter Objekte

Um häufig verwendete Objekte zwischenzuspeichern, können Sie sie mithilfe eines Arrays oder eines HashMap-Containers zwischenspeichern. Diese Methode verwendet jedoch zu viel Cache auf dem System und führt zu einer schlechten Leistung. Wir empfehlen die Verwendung eines Open Source-Tools von Drittanbietern wie EhCache. Oscache wird zwischengespeichert und implementiert grundsätzlich Caching-Algorithmen wie FIFO / FLU.

Recommended Posts

45 Techniken zur Optimierung der Java-Leistung (Teil 1)
Java-Übung Teil 1
Java-Leistung Kapitel 1 Einführung
Leistungsoptimierung für Java-Apps
Java studieren ~ Teil 8 ~ Besetzung
Java Performance Kapitel 3 Java Performance Toolbox
Java und Iterator Teil 1 Externe Iterator Edition
Java-Leistung Kapitel 2 Ansatz für Leistungstests
Apache Hadoop und Java 9 (Teil 1)
Ausnahmebehandlungstechniken in Java
Java Servlet / JSP-Anforderungsbereich Teil 1
Java mit Ramen lernen [Teil 1]
Java Servlet / JSP-Anforderungsbereich Teil 2
Grundlegende Verwendung von Java Optionaler Teil 1
Serververarbeitung mit Java (Einführung Teil.1)
Führen Sie eine Phrasenanalyse in Java 8 durch (Teil 2).
GAE / Java8-Testversion (Teil 6: "Bereitstellungsfehler")
Java-Leistung Kapitel 5 Grundlagen der Garbage Collection
Erstellen einer Phrasenanalyse in Java 8 (Teil 1)