编程知识 cdmana.com

Conseils: quelques conseils pour améliorer l'efficacité du Code Java

Préface

Optimisation du Code ,Un sujet très important.Peut - être que certains pensent que ça ne marchera pas,Qu'est - ce qu'il y a de plus petit à modifier,Qu'est - ce que la modification ou la non - modification a à voir avec l'efficacité de fonctionnement du Code?C'est ce que j'ai pensé,Comme une baleine dans l'océan,Est - ce qu'il est utile de manger une petite crevette?Ça ne marchera pas.,Mais,Après avoir mangé plus de crevettes,Les baleines sont nourries.

Il en va de même pour l'optimisation du Code,Si le projet est axé sur le plus tôt possible BUG En ligne.,Alors, on peut s'accrocher à tout le monde en ce moment,Les détails du Code ne peuvent pas être polis avec précision;Mais s'il y a suffisamment de temps pour développer、Code de maintenance,À ce stade, vous devez considérer tous les détails qui peuvent être optimisés,Un petit point d'optimisation s'accumule,Il y a certainement une amélioration de l'efficacité de fonctionnement du Code.

L'objectif de l'optimisation du Code est:

  • Réduire le volume du Code

  • Améliorer l'efficacité du fonctionnement du Code

Détails de l'optimisation du Code

1、Spécifiez la classe autant que possible、MéthodefinalModificateur

Avec final La classe du modificateur n'est pas dérivée.In Java Core API Moyenne,Il y a beaucoup d'applications final Exemples,Par exemple java.lang.String,Toute la classe est final De.Spécifier pour la classe final Un modificateur peut empêcher une classe d'être héritée,Spécifier la méthode final Le modificateur permet de ne pas outrepasser la méthode.Si une classe est spécifiée comme final,Alors toutes les méthodes de cette classe sont final De.Java Le compilateur va chercher l'occasion d'incruster tout final Méthodes,Inline pour la promotion Java L'efficacité opérationnelle joue un rôle important,Pour plus de détails, voir Java Optimisation de la période de fonctionnement.Cela permet une amélioration moyenne des performances50% .

2、Réutiliser les objets autant que possible

En particulier String Utilisation des objets,La connexion à chaîne doit se produire avec StringBuilder/StringBuffer Remplacer.Parce que Java Les machines virtuelles ne prennent pas seulement le temps de générer des objets,Il faudra peut - être aussi du temps pour récupérer et éliminer ces objets,Donc,,La génération d'un trop grand nombre d'objets aura un grand impact sur la performance du programme.

3、Utiliser des variables locales dans la mesure du possible

Les paramètres passés lors de l'appel de la méthode et les variables temporaires créées dans l'appel sont stockés plus rapidement dans la pile,Autres variables,Comme les variables statiques、Variables d'instance, etc.,Tous créés dans le tas,Plus lent.En plus,Variables créées dans la pile,À la fin de la méthode,C'est fini.,Pas besoin de recyclage supplémentaire.

4、Fermer le flux en temps opportun

Java Pendant la programmation,Connexion à la base de données、I/O Soyez prudent lors du fonctionnement du flux,Après utilisation,Fermer à temps pour libérer des ressources.Parce que l'exploitation de ces gros objets entraîne des frais généraux importants pour le système,Un peu par inadvertance.,Cela pourrait avoir de graves conséquences.

5、Réduire au minimum le double comptage des variables

Définir un concept,Appel à la méthode,Même s'il n'y a qu'une seule phrase dans la méthode,Il y a aussi de la consommation.,Inclure la création de cadres de pile、Protéger le site lorsque la méthode est appelée、Restaurer la scène à la fin de la méthode d'appel, etc.Donc, par exemple, l'opération suivante:

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

Il est proposé de le remplacer par le texte suivant::

for (int i = 0, int length = list.size(); i < length; i++) {
    ...
}

Voilà.,In list.size() Très souvent,Ça réduit la consommation.

6、Essayez d'utiliser une stratégie de chargement paresseux,C'est - à - dire créer au besoin

Par exemple:

String str = "aaa";
if (i == 1) {
    list.add(str);
}

Il est proposé de le remplacer par le texte suivant::

if (i == 1) {
    String str = "aaa";
    list.add(str);
}

7、Utilisation prudente des anomalies

Les anomalies nuisent au rendement.Lancer une exception crée d'abord un nouvel objet,Throwable L'appel du constructeur pour l'interface s'appelle fillInStackTrace() Méthode de synchronisation locale pour,fillInStackTrace() Méthode de vérification de la pile,Collecte d'informations sur le suivi des appels.Tant qu'une exception est lancée,Java La machine virtuelle doit ajuster la pile d'appels,Parce qu'un nouvel objet a été créé pendant le traitement.L'exception ne peut être utilisée que pour la gestion des erreurs,Ne devrait pas être utilisé pour contrôler le flux du programme.

8、Ne pas utiliser dans le cycletry…catch…,Il devrait être placé à l'extérieur

Sauf si.Si c'est écrit sans raison,Tant que votre chef est un peu plus âgé、Un peu obsessionnel - compulsif.,Huit réalisations vont vous gronder pour avoir écrit ce code pourri.

9、Si la longueur du contenu à ajouter peut être estimée,Une collection mise en œuvre sous forme de tableau pour la couche inférieure、La classe d'outils spécifie la longueur initiale

Par exemple, ArrayList、LinkedLlist、StringBuilder、StringBuffer、HashMap、HashSetAttendez un peu!,Par StringBuilder Par exemple:

  • StringBuilder() // Allocation par défaut16Espace de caractères

  • StringBuilder(int size) // Allocation par défautsizeEspace de caractères

  • StringBuilder(String str) // Allocation par défaut16Caractères+str.length()Espace de caractères

Peut passer par la classe(Il ne s'agit pas seulement de StringBuilder)Pour définir sa capacité d'initialisation,Cela améliore considérablement les performances.Par exemple, StringBuilderC'est parti.,length Représente le courant StringBuilder Nombre de caractères pouvant être conservés.Parce que quand StringBuilder Quand la capacité maximale est atteinte,Il va augmenter sa propre capacité à2Double plus2,Chaque fois que StringBuilder Atteindre sa capacité maximale,Il a dû créer un nouveau tableau de caractères et copier le contenu de l'ancien tableau de caractères dans le nouveau tableau de caractères—-C'est une opération très coûteuse.Imaginez.,S'il est possible de prévoir qu'il sera stocké dans un tableau de caractères5000Caractères sans spécifier la longueur,Le plus proche5000De2La puissance est4096,Chaque augmentation de capacité2Peu importe,Alors:

  • In4096 Sur la base de,Encore une demande8194Tableau de caractères de taille,Ça équivaut à une seule demande12290Tableau de caractères de taille,Si vous pouviez spécifier au début5000Tableau de caractères de taille,Plus du double de l'espace économisé;

  • Prenez l'original.4096Caractères copiés dans un nouveau tableau de caractères.

Voilà.,Gaspiller de l'espace mémoire et réduire l'efficacité du Code.Alors...,Une collection qui donne au sous - sol une implémentation de tableau、La classe d'outils ne peut pas se tromper en définissant une capacité d'initialisation raisonnable,Cela aura un effet immédiat.Mais,Attention!,Comme HashMap C'est dans un tableau+Ensemble d'implémentations de listes liées,Ne réglez pas la taille initiale comme vous l'estimez,Parce qu'un table La possibilité de ne connecter qu'un seul objet est presque0.Taille initiale recommandée2DeNPuissance secondaire,Si on peut estimer2000Éléments,Set to new HashMap(128)、new HashMap(256) Tout va bien..

10、Lorsque de grandes quantités de données sont copiées,UtiliserSystem.arraycopy()Les ordres

11、La multiplication et la Division utilisent l'opération Shift

Par exemple:

for (val = 0; val < 100000; val += 5) {
    a = val * 8;
    b = val / 2;
}

Les performances peuvent être grandement améliorées grâce à l'opération Shift,Parce qu'au bas de l'ordinateur,L'alignement est le plus pratique、Le plus rapide,Il est donc proposé de le modifier comme suit::

for (val = 0; val < 100000; val += 5) {
    a = val << 3;
    b = val >> 1;
}

Le déplacement est rapide,Mais ça pourrait rendre le Code mal compris,Il est donc préférable d'ajouter la note correspondante.

12、Ne créez pas continuellement des références d'objets dans la boucle

Par exemple:

for (int i = 1; i <= count; i++) {
    Object obj = new Object();
}

Cette approche conduit àcountPartObjectLa référence de l'objet existe,countC'est énorme.,C'est une perte de mémoire.,Lire comme suit::

Object obj = null;
for (int i = 0; i <= count; i++) {
    obj = new Object();
}

Dans ce cas,Il n'y en a qu'une en mémoire. Object Référence de l'objet,Chaque fois new Object() Quand,Object Les références d'objets pointent vers différents Object C'est tout.,Mais il n'y en a qu'une en mémoire.,Ça économise beaucoup de mémoire..

13、Considérations fondées sur l'efficacité et les contrôles de type,Doit être utilisé dans la mesure du possiblearray,Utilisé seulement si la taille du tableau ne peut être déterminéeArrayList

14、Utiliser autant que possibleHashMap、ArrayList、StringBuilder,Sauf si la sécurité du fil l'exige,Sinon, l'utilisation deHashtable、Vector、StringBuffer,Ces trois derniers entraînent des frais généraux de performance en raison de l'utilisation du mécanisme de synchronisation

15、Ne déclarez pas un tableau commepublic static final

Parce que ça n'a aucun sens.,Ceci définit simplement la référence comme suit: static final,Le contenu du tableau peut être modifié à volonté,Déclarer un tableau comme public C'est une faille de sécurité.,Cela signifie que le tableau peut être modifié par des classes externes.

16、Essayez d'utiliser le Singleton au bon endroit

L'utilisation d'un seul exemple peut réduire la charge、Réduire le temps de chargement、Améliorer l'efficacité du chargement,Mais tout ne s'applique pas à un seul cas,En termes simples,L'exemple unique s'applique principalement aux trois aspects suivants:

  • Contrôler l'utilisation des ressources,Contrôler l'accès simultané aux ressources par la synchronisation des Threads

  • Génération d'instances de contrôle,Pour réaliser des économies de ressources

  • Contrôle du partage des données,Sans lien direct,Permettre la communication entre plusieurs processus ou Threads indépendants

17、Essayez d'éviter l'utilisation arbitraire de variables statiques

Tu sais quoi?,Lorsqu'un objet est défini comme static Variable référencée par,Alors GC En général, la mémoire en tas occupée par cet objet n'est pas récupérée,Par exemple::

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

Variable statique en ce moment b Du cycle de vie A Même classe,Si A Classe non déchargée,Alors citez B Pointé B L'objet restera dans la mémoire,Jusqu'à la fin du programme.

18、Effacer les sessions inutiles à temps

Pour effacer une session qui n'est plus active,De nombreux serveurs d'application ont des temps d'arrêt de session par défaut,En général30Minutes.Lorsque le serveur d'application doit enregistrer plus de sessions,S'il n'y a pas assez de mémoire,Alors le système d'exploitation transfère une partie des données sur le disque,Le serveur d'application peut également être basé sur MRU(Le plus souvent utilisé récemment)L'algorithme décharge une partie de la session inactive sur le disque,Une exception de mémoire insuffisante peut même être lancée.Si la session doit être déchargée sur le disque,Vous devez d'abord être sérialisé,Dans les grappes à grande échelle,La sérialisation des objets est coûteuse.Donc,,Lorsque la session n'est plus nécessaire,Doit être appelé en temps opportun HttpSession De invalidate() Méthode purger la session.

19、RéalisationRandomAccessUne collection d'interfaces telles queArrayList,Les plus courants doivent être utilisésforBoucle au lieu deforeachBoucle à travers

C'est JDK Recommandé à l'utilisateur.JDK API Pour RandomAccess L'explication de l'interface est:Réalisation RandomAccess L'interface est utilisée pour indiquer qu'elle supporte un accès aléatoire rapide,L'objectif principal de cette interface est de permettre à un algorithme général de modifier son comportement,Ainsi, l'application à une liste d'accès aléatoire ou séquentiel peut fournir une bonne performance.L'expérience pratique montre que,Réalisation RandomAccess Instance de classe de l'interface,Si c'est un accès aléatoire,Utilisation normale for L'efficacité du cycle sera supérieure à celle de l'utilisation foreach Cycle;À l'envers.,Si l'accès est séquentiel,Utiliser Iterator Sera plus efficace.Un code similaire à celui qui suit peut être utilisé pour juger:

if (list instanceof RandomAccess) {
    for (int i = 0; i < list.size(); i++) {
    }
} else {
    Iterator<?> iterator = list.iterable();
    while (iterator.hasNext()) {
        iterator.next();
    }
}

Le principe sous - jacent de la boucle est l'Itérateur Iterator,Voir Java Sucre grammatical1:Paramètres de longueur variable et foreach Principe du cycle.Donc la dernière phrase“À l'envers.,Si l'accès est séquentiel,Utiliser Iterator Sera plus efficace”Cela signifie que les instances de classe qui sont accessibles séquentiellement,Utiliser foreach Boucle à travers.

20、Remplacer la méthode de synchronisation par un bloc de code de synchronisation

Ceci est dans le module Multithreading synchronized La méthode de verrouillage a été clairement décrite dans l'article,À moins qu'il ne soit certain qu'une méthode entière doit être synchronisée,Sinon, essayez d'utiliser le bloc de code de synchronisation,Évitez également de synchroniser le Code qui n'a pas besoin d'être synchronisé,Impact sur l'efficacité de l'exécution du Code.

21、Déclarer une constante commestatic final,Et nommé en majuscules

De cette façon, vous pouvez mettre ce contenu dans un pool constant pendant la compilation,Évitez de calculer la valeur de la constante générée pendant l'exécution.En plus,Nommer une constante en majuscules permet également de distinguer facilement une constante d'une variable

22、Ne créez pas d'objets inutilisés,N'importez pas de classes inutilisées

Ça n'a aucun sens,Si le Code apparaît“The value of the local variable i is not used”、“The import java.util is never used”,Alors s'il vous plaît, supprimez ce contenu inutile..

23、Évitez les réflexions pendant le fonctionnement du programme

À propos de,Voir réflexion.Le réflexe est Java Une fonctionnalité puissante pour les utilisateurs,Être puissant signifie souvent être inefficace.Il n'est pas recommandé d'utiliser le mécanisme de réflexion pendant le fonctionnement du programme, en particulier fréquemment.,En particulier Method De invoke() Méthodes,Si nécessaire,Une approche recommandée est de transformer les classes qui doivent être chargées par réflexion en un objet par une instance de réflexion et de le mettre en mémoire au début du projet—-L'utilisateur ne se soucie que d'obtenir la vitesse de réponse la plus rapide lorsqu'il interagit avec le côté opposé,Peu importe le temps qu'il faut pour démarrer un projet de bout en bout.

24、Utilisation du pool de connexion à la base de données et du pool de Threads

Les deux Pools sont utilisés pour réutiliser des objets,Le premier évite l'ouverture et la fermeture fréquentes des connexions,Ce dernier évite la création et la destruction fréquentes de fils.

25、Utiliser un flux d'entrée / sortie tamponné pourIOFonctionnement

Flux d'entrée / sortie tamponné,C'est - à - dire: BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream,Cela peut grandement améliorer IO Efficacité.

26、Plus de scénarios avec insertion séquentielle et accès aléatoire sont utilisésArrayList,Plus de scènes avec suppression d'éléments et insertion intermédiaireLinkedListC'est,Compris.ArrayListEtLinkedListLe principe de

27、Ne laissez paspublicIl y a trop de paramètres formels dans la méthode

public La méthode est la méthode fournie à l'extérieur,Si vous donnez trop de paramètres formels à ces méthodes, il y a deux inconvénients principaux:

  • Violation de l'idée de Programmation orientée objet,Java Tout est un objet,Trop de paramètres formels,Ne correspond pas à la programmation orientée objet

  • Trop d'arguments entraîneront une augmentation de la probabilité d'erreur dans l'appel de méthode

Quant à ça“Trop.”Combien de,3、4- Oui..Par exemple, nous utilisons JDBC Écris un insertStudentInfo() Méthodes,Oui.10Champs d'information de l'étudiant à insérer Student Dans le tableau,Tu peux mettre ça.10Les paramètres sont encapsulés dans une classe d'entité,En tant que insert() Paramètre formel de la méthode.

28、Variables de chaîne et constantes de chaîneequalsÉcrivez la constante de chaîne avant

C'est une petite astuce assez courante,Si les codes suivants sont disponibles:

String str = "123";
if (str.equals("123")) {
   ... 
}

Il est proposé de modifier comme suit::

String str = "123";
if ("123".equals(str))  {
    ... 
}

Ceci est principalement fait pour éviter une exception de pointeur vide.

29、Je vous en prie.,InjavaMoyenneif (i == 1)Etif (1 == i)Ça ne fait aucune différence.,Mais en termes d'habitudes de lecture,,Le premier est recommandé

D'habitude, on demande.,if (i == 1) Et if (1== i) Y a - t - il une différence?,Ça vient de C/C++ Allez..
InC/C++Moyenne,if (i == 1) Conditions de jugement valables,Oui.0Et non0Base,0Représentation false,Non0Représentation true,S'il y a un tel code:

int i = 2;
if (i == 1) { ... } else { ... }

C/C++ Jugement i==1 C'est faux.,Par conséquent,0Représentation,C'est - à - dire: false.Mais si:

int i = 2;
if (i = 1) { ... } else { ... }

Au cas où le programmeur ne ferait pas attention,Prends ça. if (i == 1) Écrit comme suit: if (i = 1),Ça pose un problème.In if À l'intérieur.iAssigner comme1,if Jugez ce qu'il contient0,Ce qui revient, c'est true C'est,Mais c'est clair. i Pour2,Les valeurs comparées sont:1,Devrait revenir false.Dans ce cas, C/C++ Est susceptible de se produire dans le développement et peut causer des erreurs incompréhensibles,Alors...,Pour éviter que les développeursifMauvaise affectation dans l'instruction,Recommandations if L'instruction est écrite comme suit::

int i = 2;
if (1 == i) { ... } else { ... }

Voilà.,Même si le développeur écrit accidentellement 1 = i,C/C++ Le compilateur peut également être vérifié pour la première fois,Parce que nous pouvons assigner une valeur à une variable i Pour1,Mais une constante ne peut pas être assignée1Pour i.

Mais,In Java Moyenne,C/C++ Ce genre de if (i = 1) La syntaxe est impossible,Parce qu'une fois cette syntaxe écrite,Java Il compile les erreurs signalées “Type mismatch: cannot convert from int to boolean”.Mais,Bien que Java De if (i == 1) Et if (1 == i) Il n'y a pas de différence sémantique,Mais en termes d'habitudes de lecture,Il serait préférable de recommander le premier.

30、Ne pas utiliser avec des tableauxtoString()Méthodes

Regardez l'utilisation du tableautoString()Ce qui est imprimé:

public static void main(String[] args) {
    int[] is = new int[]{1, 2, 3};
    System.out.println(is.toString());
}

Le résultat est:

[I@18a992f

L'intention était d'imprimer le contenu du tableau,Mais peut - être parce que les références de tableau is Exception de pointeur vide causée par NULL.Mais bien que sur le tableau toString() Ça n'a aucun sens,Mais à la collection toString() Est capable d'imprimer le contenu de la collection,Parce que le parent de la collection AbstractCollections Réécrit Object De toString() Méthodes.

31、Ne pas forcer à la baisse les types de données de base hors de portée

Cela n'obtiendra jamais le résultat souhaité:

public static void main(String[] args) {
    long l = 12345678901234L;
    int i = (int) l;
    System.out.println(i);
}

On pourrait s'attendre à ce que certains d'entre eux,Mais le résultat est:

1942892530

Expliquez - moi..Java Moyenne long - Oui.8Octets64Bitwise,Alors... 12345678901234 La représentation dans l'ordinateur devrait être:

0000 0000 0000 0000 0000 1011 0011 1010 0111 0011 1100 1110 0010 1111 1111 0010

Un int Les données de type sont4Octets32Bitwise,Avant de retirer cette chaîne de données binaires du bas32- Oui.:

0111 0011 1100 1110 0010 1111 1111 0010

Cette chaîne de binaires est exprimée en décimales 1942892530,Donc C'est la sortie sur la console au - dessus de nous.Deux autres conclusions peuvent être tirées de cet exemple:

  • Le type de données par défaut pour les entiers est int,long l = 12345678901234L,Ce chiffre est dépassé int La portée de,Donc il y a un dernier L,Ça veut dire que c'est un long Nombre de modèles.Au fait...,Le type par défaut de type flottant est double,Donc la définition float Pour écrire float f = 3.5f

  • Ensuite, écrivez une autre phrase int ii = l + i; Des erreurs seront signalées,Parce que long + int C'est un long,Impossible d'attribuer une valeur à int

32、Les données qui ne sont pas utilisées dans les classes de collection communes doivent être disponibles en temps opportunremoveLaisse tomber.

Si une classe de collection est commune(C'est - à - dire qu'il n'y a pas d'attributs dans la méthode),Les éléments de cette collection ne sont donc pas automatiquement libérés,Parce qu'il y a toujours des références à eux.Alors...,Si certaines données d'une collection publique ne sont pas utilisées au lieu de remove Laisse - les tomber.,Donc ça va faire augmenter cette collection publique,Risque de fuite de mémoire dans le système.

33、Convertir un type de données de base en chaîne,“Type de données de base.toString()C'est le moyen le plus rapide、String.valueOf(Données)Deuxième、Données+”Le plus lent

Il y a généralement trois façons de convertir un type de données de base en,J'en ai un. Integer Données de typei,Peut être utilisé i.toString()、String.valueOf(i)、i+""Trois façons,Quelle est l'efficacité des trois méthodes,Voir un test:

public static void main(String[] args) {
    int loopTime = 50000;
    Integer i = 0;
    long startTime = System.currentTimeMillis();
    for (int j = 0; j < loopTime; j++) {
        String str = String.valueOf(i);
    }
    System.out.println("String.valueOf():" + (System.currentTimeMillis() - startTime) + "ms");
    startTime = System.currentTimeMillis();
    for (int j = 0; j < loopTime; j++) {
        String str = i.toString();
    }
    System.out.println("Integer.toString():" + (System.currentTimeMillis() - startTime) + "ms");
    startTime = System.currentTimeMillis();
    for (int j = 0; j < loopTime; j++) {
        String str = i + "";
    }
    System.out.println("i + "":" + (System.currentTimeMillis() - startTime) + "ms");
}
 
 

Le résultat de l'opération est:

String.valueOf():11ms Integer.toString():5ms i + "":25ms

Plus tard, j'a i rencontré un type de données de base qui a été converti en String Quand,Utilisation prioritaire toString() Méthodes.Et pourquoi?,C'est simple.:

  • String.valueOf() La méthode sous - jacente appelle Integer.toString() Méthodes,Mais il court le jugement avant d'appeler

  • Integer.toString() Je ne dirai pas comment.,Appelé directement

  • i + ""Utilisé au rez - de - chaussée StringBuilder Réalisation,D'abord. append() Méthode d'épissage,Réutiliser toString() Méthode obtenir la chaîne

Comparez les trois,C'est évident.2Le plus rapide、1Deuxième、3Le plus lent

34、Utilisez la méthode la plus efficace pour traverserMap

Traversée Map Il y a beaucoup de façons,D'habitude, ce dont nous avons besoin dans une scène, c'est de traverser Map Dans Key Et Value,Il est donc recommandé d'utiliser、La façon la plus efficace de:

public static void main(String[] args) {
    HashMap<String, String> map = new HashMap<String, String>();
    map.put("111", "222");
    Set<Map.Entry<String, String>> entrySet = map.entrySet();
    Iterator<Map.Entry<String, String>> iter = entrySet.iterator();
    while (iter.hasNext()) {
        Map.Entry<String, String> entry = iter.next();
        System.out.println(entry.getKey() + "    " + entry.getValue());
    }
}

Si tu veux juste traverser ça MapDe key Valeur,Ça marche. Set keySet = map.keySet(); Ce serait plus approprié

35、Ressourcesclose()Opération séparée recommandée

Ça veut dire...,Comme si j'avais un code:

try {
    XXX.close();
    YYY.close();
} catch (Exception e) { ...}

Il est proposé de modifier comme suit::

try {
    XXX.close();
} catch (Exception e) { ...}
try {
    YYY.close();
} catch (Exception e) { ...}

Bien qu'il y ait des problèmes,Pour éviter les fuites de ressources.Je crois que,S'il n'y a pas de code modifié,Au cas où XXX.close() C'est une erreur de lancer,Alors c'est parti. catch C'est parti.,YYY.close() Non.,YYY Cette ressource ne serait pas recyclée,Toujours occupé,Il y a beaucoup de codes comme ça,Est susceptible de provoquer une fuite de la poignée de ressources.Et après avoir changé l'écriture ci - dessus,C'est promis, quoi qu'il arrive XXX Et YYY Sont close Laisse tomber..

版权声明
本文为[Tarzan d'Ali]所创,转载请带上原文链接,感谢
https://cdmana.com/2021/09/20210915073252798k.html

Scroll to Top