[JAVA] J'ai lu la source de ArrayList que j'ai lu

J'ai lu j'ai lu la source de ArrayList. Depuis que j'ai lu la source JDK, j'ai pensé aux points non résolus (4 places). Veuillez remplacer IntMax dans le texte par Integer.MAX_VALUE. C'était compliqué à écrire. Au début, j'ai écrit intMax, mais il est devenu IntMax. Qu'est-ce que c'est.

Mais pourquoi elementData est-il transitoire? → Non résolu

Telle est la réponse dans la partie 4. "LL.760-763 La raison pour laquelle elementData est délibérément défini sur transitoire et n'est pas écrit par defaultWriteObject () est d'éviter d'écrire plus que la taille de elementData en vain? !! 』
C'est un gaspillage de sortir null, null, null après la taille.

Mais je ne sais pas pourquoi je fais s.writeInt (size);. Où est la compatibilité de clone ()! ??

L.139 pourquoi y a-t-il un commentaire javadoc @serial ici? → Non résolu

Il semble que ce soit pour afficher les champs sérialisés de javadoc. Je le savais pour la première fois aujourd'hui. Format sérialisé Quant à savoir où voler, il existe un lien appelé format sérialisé dans les éléments associés de la classe ArrayList.

(Ajout) J'ai mal compris "ici" comme "ici". Pourquoi était-il en taille mais pas en elementData? L'avez-vous omis parce qu'il est transitoire? Mais devrais-je l'ajouter car il est sérialisé avec writeObject et readObject? Je ne sais pas parce que je n'ai jamais ajouté @serial en premier lieu. non résolu.

Le domaine autour de l'ajustement de capacité est plein de mystères et non résolus.

"Près de la valeur maximale de int → Si elle déborde de 1,5 fois et devient une valeur négative assez petite, elle sera mal jugée comme a> b, mais si a-b> 0 (selon le degré de débordement), tout va bien. 』
Même si un * 1.5 déborde et devient négatif, il est dans la plage de 32 bits lorsque l'on considère cela comme non signé. Par conséquent, le débordement peut être déterminé par un * 1.5- (IntMax-8)> 0. Bien qu'elle soit doublée dans la classe ByteArrayOutputStream, la valeur maximale immédiatement avant est a = IntMax-8, donc a * 2 = 2 * IntMax-16, et elle est jugée par un * 2- (IntMax-8) = IntMax-8> 0. ça peut. Cependant, si a = IntMax, 2 * a- (IntMax-8) = IntMax + 8 <0, et le jugement peut être manqué. Cependant, il se peut qu'il n'y ait pas de problème car le tableau IntMax ne peut pas être sécurisé avec la machine virtuelle Java actuelle. (Voir ci-dessous)

"L.244 Je ne sais pas pourquoi il est 8. 』
En fait, je me suis demandé si le tableau pouvait être sécurisé jusqu'à IntMax, mais la spécification du langage dépendait d'IntMax, mais il semble qu'il y ait moins d'implémentations de VM que cela. Par exemple, dans Oracle VM, selon Nombre maximal d'éléments de tableau en Java 32bit VM: 0x3fffffff - 3 (= 1,073,741,820) 64bit VM: 0x7fffffff - 2 (= 2,147,483,645) Il semble que ce soit le cas.

De plus, avec ByteArrayOutputStream, il existe un bogue selon lequel même une VM 64 bits ne peut être utilisée que jusqu'à environ 0x3fffffff, et il semble que cela a été corrigé. Dans Java SE 8 Update 31, la taille limite de ByteArrayOutputStream a été augmentée Avant la correction, il était défini sur IntMax lorsqu'il a débordé, mais il devient ensuite OutOfMemory, il est donc défini sur IntMax-8. IntMax-2 convient bien en considérant uniquement Oracle VM, mais il ne fonctionnera probablement pas avec d'autres VM Java. Étant donné que la source est la même que l'énorme capacité d'ArrayList, il semble que ArrayList soit également fixé à ce moment.

En outre, selon Impossible d'allouer un tableau avec des éléments Integer.MAX_VALUE, il était possible de sécuriser IntMax dans JDK 6, mais IntMax dans JDK 7 et JDK 8. Il y a un rapport de bogue disant que seulement jusqu'à -2 peuvent être sécurisés (c'est un démon). "La fermeture de ce bogue ne résoudra pas car le code actuel fonctionne comme prévu." Oui, je ne le corrigerai pas. Il semble que IntMax-headerSize (8byte) soit la limite pour la commodité de GC. Alors pourquoi IntMax-2 est-il OK? peu importe.

LL.264-270 Je ne comprends pas la signification de cette méthode. → Non résolu

"Pourquoi renvoyez-vous Integer.MAX_VALUE ici en disant Integer.MAX_VALUE --8 dans L.244? 』
Certainement drôle. Puisque IntMax-8 est la limite supérieure, je pense qu'il est plus naturel de jeter OutOfMemory s'il dépasse cela. Si vous retournez IntMax, ce devrait être OutOfMemory dans Arrays.copyOf après cela, mais c'est un peu étrange.

"Il n'est pas possible d'appeler minCapcity pour l'instant. Je ne sais pas quel genre de cas je suppose. 』
Non, je pense qu'il y a des conditions négatives. Lorsqu'il est appelé depuis public void ensureCapacity (int minCapacity) {, une vérification négative est effectuée. Il n'y a pas de contrôle négatif pour minCapacity lorsqu'il est appelé à partir de private void ensureCapacityInternal (int minCapacity) {. En d'autres termes, quand il vient de add ou addAll.

L'élément actuel elementData.length est 0x60000000, et lorsqu'il est multiplié par 1,5, il devient 0x90000000 et déborde. En revanche, si vous passez une liste de 0x60000000 à addAll, minCapacity devient 0xC0000000 et déborde.

En ce moment, if (minCapacity - elementData.length > 0) if (newCapacity - minCapacity < 0) if (newCapacity - MAX_ARRAY_SIZE > 0) Sont tous vrais et énorme La capacité est négative.

Séparément if (newCapacity - minCapacity < 0) Il n'est pas nécessaire de définir sur true, il suffit donc qu'il déborde en multipliant par 1,5 et que minCapacity déborde. Il en va de même même si addAll of List of 0x20000000 à elementData.length est 0x60000000.

à la fin

Je me suis demandé pourquoi la limite supérieure d'IntMax-8 était, donc c'était une bonne occasion d'enquêter. Ensuite, ArrayDeque est recommandé.

Recommended Posts

J'ai lu la source de ArrayList que j'ai lu
J'ai lu la source d'Integer
J'ai lu la source de Long
J'ai lu la source de Short
J'ai lu la source de Byte
J'ai lu la source de String
J'ai lu le livre de démarrage de Kotlin
DrainTo de LinkedBlockingQueue est-il sûr? J'ai suivi la source
05. J'ai essayé de supprimer la source de Spring Boot
J'ai étudié le traitement interne de Retrofit
[jour: 5] J'ai résumé les bases de Java
J'ai vérifié la partie de java.net.URL # getPath
J'ai compris les bases de la saisie de caractères
J'ai comparé les caractéristiques de Java et .NET
Je veux var_dump le contenu de l'intention
J'ai essayé d'utiliser le profileur d'IntelliJ IDEA
J'ai vérifié le nombre de taxis avec Ruby
Essayez Progate Free Edition [Java I]
[Java] Comment obtenir l'URL de la source de transition
ArrayList et le rôle de l'interface vu depuis List
J'ai examiné le cycle de vie de l'extension de JUnit Jupiter
Le monde de Clara-Rules (2)
J'étais accro au record du modèle associé
J'ai vu la liste du développement Android collectivement
J'ai essayé de réduire la capacité de Spring Boot
Jugement du calendrier
J'ai essayé le nouveau profileur de fonctionnalités d'IntelliJ IDEA 2019.2.
Le monde de Clara-Rules (4)
Je veux connaître la réponse de l'application Janken
Traitement d'image: structure de base de l'image lue par le programme
Je souhaite afficher le nom de l'affiche du commentaire
J'ai résumé le format d'affichage de la réponse JSON de Rails
Le monde de Clara-Rules (1)
Le monde de Clara-Rules (3)
Lire la source Java HashMap
J'ai lu le "Guide pratique orienté objet", donc un mémorandum
Source des objets cellulaires
Relisez le guide des rails (vue d'ensemble du contrôleur d'action)
[Java] Lors de l'écriture du source ... Mémorandum ①
J'ai écrit un diagramme de séquence de l'exemple j.u.c.Flow
Le monde de Clara-Rules (5)
J'ai résumé les types et les bases des exceptions Java
L'idée du tri rapide
Je suis parfaitement conscient de la commodité de graphql-code-generator partie 2
Je ne peux pas sortir de l'écran de la console Rails db
Je veux retourner la position de défilement de UITableView!
L'idée de jQuery
J'ai créé le côté serveur du jeu de cartes en ligne ①
Je n'ai pas vraiment compris le comportement de Java Scanner et .nextLine ()
J'ai jeté un coup d'œil à l'intérieur du Java HashMap
[Java] ArrayList → La taille doit-elle être spécifiée dans la conversion de tableau?
J'ai essayé de résumer les bases de kotlin et java
[Android] Quittez l'activité de la source de transition au moment de la transition d'écran