45 Techniques d'optimisation des performances Java (partie 1)

Préface: Puisque le japonais n'est pas natif, je pense qu'il y a pas mal d'expressions étranges et de grammaires incorrectes, donc j'apprécierais que vous puissiez le signaler.

Dans les programmes JAVA, la plupart des problèmes de performances ne sont pas dans le langage JAVA, mais dans le programme lui-même. Il est important de développer de bonnes habitudes de codage qui peuvent améliorer considérablement les performances de votre programme.

Assurez-vous d'utiliser Singleton au bon endroit

Les tonnes uniques réduisent la charge de charge, réduisent les temps de chargement et améliorent l'efficacité de la charge, mais tous les emplacements ne conviennent pas pour des tonnes uniques.

En termes simples, Singleton peut être appliqué à trois situations principales:

  1. Contrôlez l'utilisation des ressources et contrôlez l'accès simultané aux ressources via la synchronisation des threads.
  2. Contrôlez la génération d'instances pour atteindre l'objectif de protection des ressources.
  3. Vous souhaitez contrôler le partage des données et autoriser la communication entre plusieurs processus ou threads indépendants sans établir d'association directe.

2. N'utilisez pas librement les variables statiques

Si un objet est défini comme une variable statique, GC ne récupère généralement pas la mémoire occupée par cet objet.

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

À ce stade, le cycle de vie de la variable statique b est synchronisé avec la classe A. Si la classe A n'est pas déchargée, l'objet b restera en mémoire jusqu'à ce que le programme se termine.

3. Ne créez pas trop d'objets Java

Non seulement le système prend beaucoup de temps pour créer des objets, mais il faut également beaucoup de temps pour ramasser les ordures et traiter ces objets, alors assurez-vous d'éviter de créer de nouveaux objets dans des boucles et des méthodes fréquemment appelées. .. Il est préférable de remplacer l'objet par un type de données ou un tableau de base.

4. Essayez d'utiliser le modificateur final

Les classes avec le modificateur final ne peuvent pas être dérivées. Il existe de nombreux exemples d'API Java Core avec des finales telles que java.lang.String. Par exemple, la spécification de final dans la classe String empêche l'utilisateur de remplacer la méthode length (). De plus, si la classe est finale, toutes les méthodes de cette classe seront finales. Le compilateur Java recherche des opportunités pour insérer toutes les méthodes finales (ceci est pertinent pour l'implémentation d'un compilateur particulier). Cela améliorera les performances de 50% en moyenne.

5. Utilisez autant que possible des variables locales

Lorsque la méthode est appelée, les paramètres passés et les variables temporaires créées par l'appel sont plus rapides à être stockées sur la pile. D'autre part, d'autres variables telles que les variables statiques et les variables d'instance sont créées dans le tas et sont plus lentes que la pile.

6. Essayez de gérer à la fois la boxe et les types primitifs

La boxe et les types primitifs peuvent être convertis les uns aux autres pendant l'utilisation. Cependant, les zones de mémoire générées par les deux sont complètement différentes. La génération et le traitement des types primitifs sont traités sur la pile et, comme les types de boîtes sont des objets, ils sont instanciés dans le tas. L'utilisation de types primitifs est recommandée sauf dans les situations où un traitement de type boîte est requis, comme les collections.

7. Minimiser la synchronisation

Comme nous le savons tous, la synchronisation est une surcharge système importante et peut même entraîner des blocages, essayez donc d'éviter un contrôle de synchronisation inutile. Lorsque la méthode de synchronisation est appelée, l'objet actuel est verrouillé directement et aucun autre thread ne peut appeler d'autres méthodes de l'objet actuel tant que la méthode n'est pas terminée. Par conséquent, la méthode de synchronisation est minimisée et la synchronisation de méthode doit être utilisée à la place de la synchronisation de bloc de code.

8. N'utilisez pas la méthode finalize

La charge de travail du GC est si lourde que l'application s'arrêtera, en particulier si la mémoire Young est recyclée, donc si vous utilisez la méthode de finalisation pour nettoyer les ressources à ce moment, le GC sera surchargé et le fonctionnement du programme sera lent. Devenir.

9. Essayez d'utiliser des types de données de base au lieu d'objets

String str = "hello";

Le code ci-dessus créera une chaîne "hello" et le pool de cache de caractères de la JVM mettra également en cache cette chaîne.

String str = new String("hello");

À ce stade, en plus de créer une chaîne, l'objet String référencé par str contient également un tableau char []. Ce tableau contient h, e, l, l, o.

10. Pour le multithreading, utilisez HashMap et ArrayList autant que possible lorsque vous n'avez pas besoin de prendre en compte la sécurité des threads

HashTable, Vector, etc. utilisent un mécanisme de synchronisation, ce qui réduit les performances.

11. Créez un HashMap le plus rationnel possible

Si vous souhaitez créer un HashMap volumineux, spécifiez autant que possible la capacité et le facteur de charge dans le constructeur ci-dessous.

public HashMap(int initialCapacity, float loadFactor);

Évitez d'étendre HashMap. L'expansion est très coûteuse.

Par défaut, la capacité initiale est de 16 et le loadFactor est de 0,75, mais il est important d'estimer avec précision l'espace dont vous avez besoin et la taille optimale dont vous avez besoin. La même chose est vraie pour Hashtable et Vectors.

12. Réduire le double calcul des variables

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

dans le cas de

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

Doit être remplacé par.

N'utilisez pas d'expressions complexes dans les boucles. Dans les boucles, les conditions de boucle sont calculées de manière itérative. En ne modifiant pas la valeur de la condition de boucle sans utiliser d'expressions complexes, le programme s'exécute plus rapidement.

13. Essayez d'éviter une instanciation inutile

Par exemple:

A a = new A();

if(i==1){

  list.add(a);

}

dans le cas de,

if(i==1){

  A a = new A();

  list.add(a);

}

Devrait être remplacé par.

14. Enfin des ressources gratuites avec des blocs

Les ressources utilisées par le programme doivent être libérées pour éviter les fuites de ressources. Ceci est mieux fait dans un bloc final. Quel que soit le résultat de l'exécution du programme, les blocs finally sont toujours exécutés pour garantir une fermeture correcte des ressources.

15. Utilisons l'opération de décalage au lieu de "a / b"

Le "/" est une opération très coûteuse et est plus rapide et plus efficace avec les opérations de quart. Par exemple

int num = a / 4;

int num = a / 8;

dans le cas de,

int num = a >> 2;

int num = a >> 3;

Devrait être remplacé par. Cependant, l'opération de décalage est intuitive et difficile à comprendre, il est donc préférable d'ajouter des commentaires lors de l'utilisation de shift.

16. Utilisons l'opération de décalage au lieu de "a * b"

De même, pour les opérations «*», il est plus rapide et plus efficace d'utiliser les opérations de décalage.

Par exemple

int num = a * 4;

int num = a * 8;

dans le cas de,

int num = a << 2;

int num = a << 3;

Devrait être remplacé par.

17. La capacité de StringBuffer doit être déterminée à l'avance autant que possible.

Le constructeur StringBuffer crée un tableau de caractères de taille par défaut (généralement 16). Si cette taille est dépassée pendant l'utilisation, la mémoire sera réallouée, un tableau plus grand sera créé, le tableau d'origine sera copié et l'ancien tableau sera rejeté.

Dans la plupart des cas, vous pouvez spécifier la taille lorsque vous créez le StringBuffer. Cela évite l'auto-expansion qui se produit lorsqu'il n'y a pas assez de capacité et peut améliorer les performances.

18. Libérez les références aux objets inutiles dès que possible

Dans la plupart des cas, le programme n'a pas besoin de définir explicitement la variable de référence sur null, car l'objet référencé par la variable de référence locale de la méthode sera dans la plupart des cas mis à la corbeille à la fin de la méthode.

Par exemple

Public void test(){

Object obj = new Object();

……

obj=null;

}

Dans le code ci-dessus, vous n'avez pas besoin d'exécuter explicitement «obj = null».

La référence à obj est libérée lorsque l'exécution de la méthode test () est terminée.

Mais si le programme est modifié comme suit:

public void test(){

Object obj = new Object();

// ……

Obj=null;

//Les opérations chronophages, gourmandes en mémoire ou les méthodes gourmandes en temps et en mémoire sont appelées

// ……

}

À ce stade, en attribuant explicitement null à obj, la référence à Object peut être libérée à un stade précoce.

19. Évitez autant que possible d'utiliser des tableaux à deux dimensions

Les données bidimensionnelles occupent beaucoup plus d'espace mémoire qu'un tableau unidimensionnel. C'est environ 10 fois.

20. N'utilisez pas de split

Comme split prend en charge les expressions régulières, il est relativement inefficace et consomme beaucoup de ressources. Pensez à utiliser StringUtils.split (string, char) d'Apache, qui peut être fréquemment mis en cache.

21. ArrayList et LinkedList

L'un est une table linéaire, l'autre est une liste chaînée et, en conclusion, ArrayList est meilleur que LinkedList si vous appelez get fréquemment. Pour LinkedList, vous devez numériser un par un. D'un autre côté, si vous appelez fréquemment add ou remove, LinkedList est meilleur que ArrayList. ArrayList doit déplacer des données.

Ceci est une analyse théorique. Comprenez la structure des données des deux et prenez les mesures appropriées en fonction de la situation.

22. Utilisez System.arraycopy () au lieu de boucler et de copier un tableau

System.arraycopy () est beaucoup plus rapide que de boucler et de copier un tableau.

23. Cache les objets fréquemment utilisés

Pour mettre en cache les objets fréquemment utilisés, vous pouvez les mettre en cache à l'aide d'un tableau ou d'un conteneur HashMap. Cependant, cette méthode utilise trop de cache sur votre système et entraîne de mauvaises performances. Nous vous recommandons d'utiliser un outil open source tiers tel que EhCache. Oscache est mis en cache et implémentent essentiellement des algorithmes de mise en cache tels que FIFO / FLU.

Recommended Posts

45 Techniques d'optimisation des performances Java (partie 1)
java pratique partie 1
Java Performance Chapitre 1 Introduction
Réglage des performances de l'application Java
Étudier Java ~ Partie 8 ~ Cast
Java Performance Chapitre 3 Boîte à outils Java Performance
Java et Iterator Part 1 External Iterator Edition
Java Performance Chapter 2 Approche des tests de performances
Apache Hadoop et Java 9 (partie 1)
Techniques de gestion des exceptions en Java
Portée de la requête Java Servlet / JSP, partie 1
Java pour apprendre avec les ramen [Partie 1]
Portée de la requête Java Servlet / JSP, partie 2
Utilisation de base de Java Facultatif Partie 1
Traitement serveur avec Java (Introduction partie 1)
Faire une analyse de phrase en Java 8 (partie 2)
Essai GAE / Java8 (Partie 6: «Échec du déploiement»)
Java Performance Chapitre 5 Bases de la récupération de place
Création d'une analyse de phrase dans Java 8 (partie 1)