Comment améliorer les performances des applications Java en 10 étapes
Vivre à l’ère du numérique est autant une bénédiction qu’une frustration. Lorsque les ordinateurs et les applications fonctionnent correctement, nous avons tendance à les tenir pour acquis. Mais lorsqu’un ordinateur se bloque ou qu’une application enlise un ordinateur portable ou un appareil mobile, de mauvaises performances augmentent le stress.
Que vous soyez un développeur ayant accès au code source ou simplement un utilisateur final essayant d'accélérer une application Java extrêmement lente, nous avons une bonne nouvelle : vous pouvez prendre certaines mesures pour améliorer les performances.
Java est-il identique à JavaScript ?
Bref, non ; Java et JavaScript sont deux technologies complètement différentes. Bien qu’il s’agisse de technologies orientées objet, Java est un environnement de développement dans lequel les programmeurs peuvent coder des applications conçues pour s’exécuter localement dans la mémoire physique d’un système.
JavaScript, quant à lui, a été conçu pour créer des applications Web et coïncide fréquemment avec d'autres technologies Web telles que HTML et CSS. Aujourd'hui, nous allons examiner les meilleurs moyens d'améliorer les performances des applications écrites en Java, mais pas en JavaScript.
Causes des mauvaises performances des applications
Les causes d’une application peu performante sont nombreuses, même si les causes principales sont une petite poignée de problèmes. Naturellement, les deux premières causes sont une mauvaise conception et un codage médiocre.
Bien que les IDE et les éditeurs de code mettent en avant les tests et les objets pour les rendre plus lisibles par l’homme, il existe un fossé de communication entre les ordinateurs et les humains. Vous allez commettre des erreurs lors de la création d’une application – il n’y a aucun moyen de contourner cela.
Parfois, l’ordinateur ne comprend pas votre intention. Au contraire, il ne fait qu’exécuter les instructions qui lui sont données. Outre les défauts d’algorithme et de codage, le manque de ressources est une autre cause fréquente.
Le matériel local comme les cycles de RAM et de processeur affecte les performances des applications, tout comme d'autres ressources comme la bande passante du réseau. De plus, notez que les problèmes locaux du système d’exploitation affectent souvent les performances des applications.
Comment améliorer les performances des applications Java – 10 étapes
Avant d'approfondir chaque étape spécifique, nous souhaitions vous donner un aperçu général de la manière d'améliorer les performances et la vitesse des applications Java, comme suit :
- Effectuer le profilage et les tests de charge – le profilage de votre application Java aidera à découvrir les points faibles et les goulots d'étranglement.
- Nettoyer le code et réviser les algorithmes – un code propre est plus facile à maintenir, modifier, lire et affiner ; l'ajustement de vos algorithmes réduit les appels de fonctions tautologiques.
- Évitez la récursion lorsque cela est possible – la récursivité est un mal nécessaire dans certains cas, même si elle doit être utilisée avec parcimonie.
- Mettre à niveau le matériel du système – les mauvaises performances des applications ne peuvent pas être dues à un code et à des algorithmes médiocres ; au lieu de cela, la cause sous-jacente peut être liée au système exécutant l’application.
- Augmentez la bande passante LAN et WAN – toutes les fonctions n'interagissent pas avec le matériel local ; si votre application communique avec des systèmes distants, votre infrastructure réseau peut en être la cause.
- Rangez votre système d'exploitation – les systèmes d'exploitation en désordre ont besoin d'une maintenance pour exécuter les applications au mieux de leurs capacités.
- Utilisez StringBuilder pour une efficacité améliorée – les chaînes sont presque inévitables dans la plupart des applications, mais l'opération « += » est très inefficace.
- Exploitez la mise en cache pour améliorer les performances – la mise en cache est l’un des meilleurs moyens de réduire les instanciations d’objets et les appels de fonctions redondants.
- Privilégiez la pile plutôt que le tas – la pile est plus efficace vis-à-vis des ressources système car elle se maintient et libère la mémoire occupée par les objets défunts.
- Influencer la gestion de la mémoire– en dernier recours, accéder à la mémoire tas est parfois nécessaire. Cela vous demandera de choisir la bonne méthode de collecte des ordures.
Cela dit, approfondissons un peu chaque méthode pour améliorer les performances des applications Java.
Article similaire: Surveillance Apache Tomcat
1. Effectuer le profilage et les tests de charge
La première étape pour améliorer les performances des applications Java consiste à identifier les domaines à améliorer. Sans savoir où se situent les plus gros problèmes, essayer d’accélérer une application revient à lancer une fléchette sur un jeu de fléchettes avec les yeux bandés. Heureusement, il existe des outils logiciels qui collectent des données sur les performances des applications.
Le premier outil que nous recommandons d’utiliser est le logiciel de profilage Java. Un tel exemple est VotreKit , qui est une solution adaptée aux entreprises ainsi qu’aux utilisateurs individuels. VotreKit propose une variété de licences telles que des options d'entreprise, académiques, open source et par siège.
Ses fonctionnalités incluent, sans s'y limiter, les éléments suivants :
- Profilage des performances du processeur
- Profilage des performances de la mémoire
- Détection de fuite de mémoire
- Analyse des threads et de la synchronisation
- Tests de performances Web, bases de données et E/S
Cet outil a été conçu pour être utilisé sur des systèmes locaux, des systèmes distants, des projets en cours de développement et même des logiciels de production. VotreKit n'est cependant pas le seul profileur Java de qualité et est fortement concurrencé par d'autres solutions comme EJ Technologies , qui a créé le JProfils .
Cet outil est très similaire à VotreKit et fournit des options de test pour les sessions locales et distantes, les déclencheurs hors ligne, les comparaisons d'instantanés, le suivi des demandes (HTTP, RMI, service Web, EJB, événements AWT, démarrages de threads, etc.) et la création de sondes personnalisées parmi de nombreuses autres fonctionnalités. Dernièrement, JProfils dispose également d'outils de profilage de matériel, de threads, de télémétrie et de base de données.
2. Nettoyer le code et réviser les algorithmes
Le code source d’un logiciel est comme la première ébauche d’un roman : il n’est jamais parfait après la première itération et nécessite des révisions importantes avant d’être finalement peaufiné. Avant tout, vous devez vous efforcer d’écrire du code propre et saturé de commentaires afin de pouvoir naviguer dans votre texte et de vous rappeler facilement pourquoi chaque objet a été instancié et pourquoi chaque fonction a été appelée.
Bien que garder votre code propre n'accélère pas à lui seul une application Java, cela vous aide à éliminer plus efficacement le code inutile et à rechercher les faiblesses et les redondances dans vos algorithmes. Un code propre rend également le processus de débogage plus fluide et vous aide à corriger les erreurs (comme les fuites de mémoire) que vous avez identifiées après le profilage et le test de charge de votre logiciel.
Profileur Java APM Datadog (ESSAI GRATUIT)
Une autre option à considérer est le profileur Java qui fait partie du APM Datadog emballer. Ce gestionnaire d'applications est un système basé sur le cloud. Il suit l'utilisation des ressources des applications Java par classe et méthode et offre une vue étape par étape du code Java, en suivant l'exécution via les API et les appels de fonction. Le service suit également des mesures plus larges de performances des applications et des sites Web, telles que la disponibilité et les temps de réponse.
Datadog APM Java Profiler Commencez un essai GRATUIT de 14 jours
3. Évitez la récursion lorsque cela est possible
La récursivité est une stratégie de programmation de base dans laquelle une fonction s'appelle pour résoudre un problème. La récursion n’est pas nécessairement mauvaise, mais c’est une arme à double tranchant. Il présente des avantages et des utilisations pratiques. Par exemple, la récursion rend le code plus propre et plus compact et réduit les itérations tautologiques des boucles et des fonctions.
Étant donné que la récursivité réduit la complexité et le volume du code, elle facilite la maintenance d'une application Java. Malheureusement, ces avantages se font au détriment des performances des applications. La récursivité et les appels de fonctions sont coûteux en termes de vitesse et de performances car ils nécessitent des fonctions pop et push sur la pile.
En revanche, une solution plus efficace à la récursion est le bouclage. Les opérations de bouclage peuvent être plus difficiles à lire et sont composées de plus de caractères et de code source que la récursion, mais elles sont préférables lorsque les performances de l'application doivent être maximisées. Il n'est peut-être pas toujours pratique de renoncer complètement à la récursion, mais l'atténuer autant que possible contribuera à améliorer les performances des applications Java.
4. Mettre à niveau le matériel du système
À première vue, il peut sembler qu’une application Java peu performante soit due à un problème logiciel. Même si cela peut sembler contre-intuitif, la cause première d’une mauvaise performance peut être un problème matériel. Que vous exécutiez une application Java localement ou à distance, le système sur lequel l'application Java est exécutée peut ne pas disposer de suffisamment de ressources système pour exécuter le code de manière satisfaisante.
Le composant le plus simple à mettre à niveau et qui a généralement un impact direct sur les performances du logiciel est la RAM. En augmentant la quantité de mémoire physique de votre ordinateur, vous réduisez le risque que le système manque d'espace de stockage pour les données d'application et soit obligé de revenir à l'utilisation du disque dur comme RAM impromptue. Cette pratique est connue sous le nom de fichier d'échange et, bien qu'elle ait des utilisations pratiques, les fichiers d'échange sont plus indésirables pour les applications hautes performances que la RAM, car le processus de lecture et d'écriture est nettement plus lent sur un disque dur.
De plus, si votre application Java interagit de manière significative avec le disque dur (comme une application de sauvegarde ou de synchronisation de données), la mise à niveau du disque dur peut améliorer les performances du système. Par exemple, vous pouvez passer à un lecteur avec des RPM plus élevés pour des procédures de lecture et d'écriture plus rapides. Notez cependant que les disques durs les plus rapides sont les SSD (Solid State Drives) et ne contiennent aucune pièce mobile. Enfin, certains systèmes, mais pas tous, sont également capables d’étendre le processeur, même si cette mise à niveau n’est pas aussi simple que la RAM.
5. Augmentez la bande passante LAN et WAN
Bien que le matériel local et serveur soit un composant clé des applications Java, y compris les applications Web Java, ce n'est pas le seul goulot d'étranglement potentiel. Que vous hébergez des applications Web Java localement sur un réseau local, sur un intranet ou à distance, la bande passante joue un rôle crucial en ce qui concerne la disponibilité et les performances de vos applications, en particulier pendant les périodes de charge de pointe.
De manière générale, la bande passante LAN est abondante et peu coûteuse, tandis que la bande passante WAN est chère et rare. Néanmoins, d'autres trafics LAN peuvent évincer le réseau local auquel le serveur exécutant les applications Web Java est connecté. Ce problème peut être résolu de deux manières.
Tout d’abord, vous pouvez choisir de mettre à niveau les commutateurs et l’infrastructure réseau locale vers une solution Gigabit Ethernet ou 10 Gigabit Ethernet pour réduire la congestion du réseau. Vous pouvez également mettre en œuvre une politique QoS (Qualité de service) qui donne la priorité au trafic vers et depuis le serveur hébergeant les applications Java par rapport aux autres types de trafic.
De plus, en plus d'augmenter la bande passante WAN (ce qui peut nécessiter la sélection d'un autre FAI), vous pouvez mettre en œuvre un équilibrage de charge pour mieux tirer parti des connexions FAI redondantes. N'oubliez pas que les applications Java peu performantes ne sont pas nécessairement dues à des problèmes logiciels et peuvent être affectées par la congestion du réseau.
6. Rangez votre système d'exploitation
Les systèmes d'exploitation nécessitent un entretien et une maintenance pour fonctionner à des performances optimales et utiliser efficacement les ressources du système. Un système d’exploitation négligé a tendance à ralentir et à paraître lent. Par exemple, vous pouvez avoir de nombreux processus invisibles exécutés en arrière-plan dont vous ignoriez même l’existence.
De plus, la procédure d'installation de nombreuses applications ajoute automatiquement un nouveau logiciel à la liste des applications qui se lancent au démarrage. Non seulement ces applications ralentissent le démarrage du système, mais elles monopolisent également des ressources système vitales telles que les cycles de RAM et de processeur qui pourraient autrement être utilisées pour exécuter une application Java.
L'élagage des processus et applications nécessaires et indésirables aidera à ranger votre système d'exploitation, tout comme l'exécution d'un nettoyeur de registre sur les systèmes Windows. Un nettoyeur de registre peut atténuer et éliminer les erreurs DLL et les erreurs d'exécution en supprimant les entrées erronées dans le registre et en régénérant les structures d'index.
De plus, une autre tâche ménagère – qui doit être utilisée avec parcimonie – consiste à défragmenter votre disque dur. Au fil du temps, à mesure que les fichiers sont continuellement écrits et supprimés d’un disque dur, ils peuvent devenir un désordre tentaculaire et chaotique. Un outil de défragmentation rassemble toutes vos données et les réécrit en blocs contigus, ce qui réduit le temps nécessaire au disque dur pour lire les informations.
Mais soyez prévenu : le processus de défragmentation est très exigeant et éprouvant pour le disque dur. Si vous le défragmentez quotidiennement, hebdomadairement ou même mensuellement, vous réduirez considérablement la durée de vie de votre disque dur. Une fréquence plus raisonnable et plus pratique est d'environ deux à trois fois par an.
7. Utilisez StringBuilder pour une efficacité améliorée
Les chaînes sont un type de données courant dans la grande majorité des applications – elles sont assez difficiles à éviter ou à ignorer. Malheureusement, la concaténation de chaînes est aussi inefficace que fréquente. Il peut sembler que la meilleure façon de concaténer des chaînes est d'utiliser l'opération « + = », mais il s'agit d'une opération surutilisée qui est extrêmement inefficace.
Le problème est que l'opération « + = » alloue une chaîne entièrement nouvelle à chaque fois qu'elle est utilisée, ce qui peut créer de nombreuses données de chaîne redondantes et inutiles. Bien que l'utilisation de cette opération de temps en temps n'entraîne pas l'arrêt de votre application Java, chaque petite opération s'additionne. Imaginez combien de fois cette inefficacité pourrait être amplifiée en boucle ?
Heureusement, il existe une alternative plus efficace. Le Générateur de chaînes object a été conçu comme une alternative efficace aux opérations de concaténation de base. Prenez l'habitude d'utiliser ce type de données au lieu d'utiliser le raccourci paresseux de l'opération « + = » si vous souhaitez améliorer les performances des applications Java.
8. Exploitez la mise en cache pour améliorer les performances
La mise en cache est l'un des moyens les plus efficaces d'augmenter l'efficacité des applications Java. Le concept principal de la mise en cache est de consolider plusieurs appels et fonctions en une seule ressource réutilisable. Bien qu’il existe de nombreuses formes de mise en cache, lorsque la plupart des gens parlent ici de « mise en cache », la première chose qui leur vient à l’esprit est la technologie des bases de données.
Non seulement les données contenues dans une base de données peuvent être mises en cache localement pour économiser la bande passante, mais le volume élevé de connexions à la base de données peut également ralentir une application. Sachez néanmoins qu’il ne faut pas abuser de la mise en cache. Vous pourriez intuitivement penser que tout devrait être mis en cache au cas où vous auriez besoin de l’utiliser à nouveau dans un avenir proche. Cependant, vous devez vous assurer que les données et les connexions que vous mettez en cache sont suffisamment nombreuses pour constater un gain de performances.
9. Privilégiez la pile plutôt que le tas
Pour améliorer les performances des applications Java, stockez vos données sur la pile plutôt que sur le tas. Pourquoi demandes-tu? Parce qu'il utilise la mémoire plus efficacement et supprime les données qui ont déjà rempli leur fonction. Non seulement la pile utilise les ressources plus efficacement, mais elle contrôle également les frais généraux. La meilleure façon de privilégier la pile par rapport au tas est d’éviter d’instancier des classes wrapper.
Tout comme pour l’utilisation de la récursivité, il n’est pas toujours faisable (ni même possible) de renoncer à l’utilisation d’une classe wrapper. Mais en règle générale, vous devez utiliser par défaut des types de données primitifs comme « int » par opposition à Integer. Le nombre de gains de performances que vous pouvez récolter en utilisant cette tactique dépend d’une myriade de facteurs. Néanmoins, privilégier la pile est un bon guide pour trouver le chemin vers le code Java le plus simple et le plus efficace.
Il existe des outils sur le marché pour vous aider à mettre à jour avec succès les correctifs Java. Un de ces outils est Vents solaires Gestionnaire de correctifs .
Vous pouvez télécharger un fichier entièrement fonctionnel30 jours d'essai gratuit
SolarWinds Patch Manager Téléchargez un essai GRATUIT de 30 jours
En rapport: Meilleurs outils de gestion des correctifs
De plus, vous devriez consulter le Outil de surveillance Java SolarWinds pour les serveurs d'applications avec Server & Application Monitor pour améliorer les performances. Vous pouvez télécharger un fichier entièrement fonctionnel30 jours d'essai gratuit.
Outil de surveillance Java SolarWinds pour serveurs d'applications avec SAM Téléchargez la version d'essai GRATUITE de 30 jours
10. Influencer la gestion de la mémoire
Bien qu’il soit préférable d’utiliser la pile plutôt que d’accéder à la mémoire tas, cela est parfois inévitable. Le gros problème de performances concerne la disponibilité de la mémoire, car un manque de mémoire ralentira toutes vos applications et les applications Java sont particulièrement dépendantes de la mémoire.
La JVM se charge de libérer de la mémoire en supprimant les objets non référencés, qui ne sont plus dans la portée, via des garbage collectors. Cependant, c’est un mythe que le ramassage des déchets soit une boîte noire et qu’il n’existe aucun moyen d’influencer son comportement. Vous pouvez ajuster la taille du tas et modifier l'algorithme de récupération de place du tas. Il est également possible de modifier la proportion de tas de nouvelle génération par rapport à la taille du tas d'ancienne génération. Il existe donc de nombreuses façons d’améliorer la gestion de la mémoire et de modifier la fréquence de collecte de l’espace mémoire abandonné.
Un gros problème de performances avec les garbage collector est qu'ils gèlent les threads d'application pendant les opérations de libération de mémoire. Il est donc important de choisir la bonne stratégie de garbage collection selon que vous donnez la priorité à la vitesse, à l’évolutivité ou à l’optimisation du processeur.
Les quatre options sont :
- Collecteur de déchets en série – Pour un environnement monothread. Bon pour l’optimisation du processeur mais pas bon pour l’évolutivité.
- Collecteur de déchets parallèle – Il s’agit de la valeur par défaut et elle est conçue pour les systèmes multithread. Comme Serial GC, il gèle tous les threads d'application lors de la collecte. Utilise beaucoup de CPU.
- Balayage de marques simultané – Supprime sélectivement les gestionnaires de mémoire, libérant ainsi des zones d'espace. Gèlera uniquement les processus qui accèdent à la même zone de mémoire en cours d'ajustement. Très gourmand en CPU mais idéal pour l'évolutivité.
- Collecteur de déchets G1 – Segmente les grands espaces de mémoire tas en segments. Bloque uniquement les applications qui tentent d'accéder à une région en cours de collecte. Bon pour l’optimisation et l’évolutivité du processeur, mais crée une surcharge en mémoire.
FAQ sur les performances des applications Java
Comment gérez-vous les problèmes de performances en Java ?
La plupart des problèmes de performances avec le code Java ne sont pas liés au code lui-même mais à la disponibilité des ressources système. Par conséquent, attendez-vous à ce que des problèmes surviennent une fois le code en ligne et qui n’ont pas été détectés lors du développement. Réexaminez les performances à chaque étape du cycle de vie du système.
Comment optimiser le code d’une application Java ?
Évitez une allocation de tas surdimensionnée dans votre code en commençant par l'allocation de mémoire minimale dans le code, puis ajoutez de l'espace plus tard s'il semble que davantage soit nécessaire. Cherchez à renforcer toute procédure permettant de verrouiller les ressources et d'optimiser les récupérations de données SQL en examinant l'optimisation SQL : le manque de ressources et les interactions avec d'autres systèmes constituent les principales causes de problèmes de performances dans le code Java.
La conversion de mon application Java en Node.js améliorera-t-elle les performances ?
Soyez prudent lorsque vous changez de système, en particulier vers de nouveaux cadres de programmation que vous ne connaissez pas. Node.js est loué pour sa rapidité, mais il ne possède peut-être pas toutes les fonctionnalités dont vous avez besoin pour votre application. Si vous êtes tenté par Node.js, écrivez d'abord une nouvelle application dans cet environnement plutôt que d'essayer de la porter sur un programme Java existant. Si vous rencontrez des problèmes avec les performances de Java, il s'agit probablement d'un problème de disponibilité des ressources, qui persistera quel que soit le framework dans lequel vous avez écrit le code.
Si vous avez des histoires personnelles ou des anecdotes concernant l'accélération des applications Java, nous vous invitons à commenter ci-dessous.