À propos du comportement lors de la création d'un mappage de fichiers avec Java

À propos du comportement lors de la création d'un mappage de fichiers avec Java

J'ai étudié le comportement lorsque le mappage de fichiers est effectué en Java, je vais donc le résumer.

Environnement CentOS7.3.1611, openjdk-1.8.0.131

Vous pouvez utiliser l'appel système open + mMap en langage C pour mapper des fichiers à la mémoire, mais j'ai toujours été préoccupé par son utilisation en Java. Je vais vraiment l'essayer.

Évaluez avec les sources suivantes.

mmap01.java


import java.lang.Thread;
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class mmap01
{
  public static void main(String[] args) throws Exception
  {
    for (int argc = 0; argc < args.length; argc++ ) {
      File file = new File(args[argc]);
      long length = file.length();

      System.out.println("file:" + args[0] + "  size:" + length);
      MappedByteBuffer in = new RandomAccessFile(file, "r")
                                .getChannel().map(FileChannel.MapMode.READ_ONLY, 0, length);
      for (long i = 0; i < length; i++) {
        in.get();
      }
      System.out.println("Finished reading");
    }
    System.out.println("wait");
    Thread.sleep(1000000);
  }
}

Cartographions-le réellement.

Par ailleurs, dans le cas d'un fichier qui dépasse Integer.MAX_VALUE (2 ^ 31), l'erreur suivante se produira au moment de la mappe. J'ai pu cartographier avec une taille de 2 ^ 31-1.

$ dd if=/dev/zero of=2gb bs=1 seek=2147483647 count=1
$ dd if=/dev/zero of=2gb-1 bs=1 seek=2147483646 count=1
$ dd if=/dev/zero of=2gb-2 bs=1 seek=2147483645 count=1
$ java mmap01 2gb
file:2gb  size:2147483648
Exception in thread "main" java.lang.IllegalArgumentException: Size exceeds Integer.MAX_VALUE
	at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:869)
	at mmap01.main(mmap01.java:17)
$ java mmap01 2gb-1
file:2gb-1  size:2147483647
Finished reading
wait

À ce stade, l'état de la mappe de mémoire du processus java et l'état de Java sont les suivants. Il semble être mappé avec mmap. D'après les résultats de jstat, il semble que la zone mappée soit hors du tas.

$ cat /proc/$(pidof java)/maps
(Abréviation)
7f97c8000000-7f9848000000 r--s 00000000 00:26 5                          /mnt/hgfs/COMMON/Java_Mmap/2gb-1
(Abréviation)
$ jstat -gc $(pidof java)
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
1024.0 1024.0  0.0    0.0    8192.0   671.9    20480.0      0.0     4480.0 866.3  384.0   73.9       0    0.000   0      0.000    0.000

Que se passe-t-il lorsque plusieurs fichiers sont mappés?

$ java mmap01 2gb-1 2gb-2
file:2gb-1  size:2147483647
Finished reading
file:2gb-1  size:2147483646
Finished reading
wait

Les deux fichiers sont correctement mappés. Le tas n'a pas augmenté autant que la zone de lecture supplémentaire (2 ^ 31-2).

$ cat /proc/$(pidof java)/maps
(Abréviation)
7fd08c000000-7fd10c000000 r--s 00000000 00:26 6                          /mnt/hgfs/COMMON/Java_Mmap/2gb-2
7fd10c000000-7fd18c000000 r--s 00000000 00:26 5                          /mnt/hgfs/COMMON/Java_Mmap/2gb-1
(Abréviation)
$ jstat -gc $(pidof java)
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
1024.0 1024.0  0.0    0.0    8192.0   835.7    20480.0      0.0     4480.0 866.3  384.0   73.9       0    0.000   0      0.000    0.000

Même ainsi, pourquoi avons-nous fixé une limite de 2 Go sur la zone cartographiable? Il est également difficile à gérer car il n'existe pas de méthode de démappage explicite. Notes sur DirectByteBuffer et comparaison des performances a également une description de la version.

référence

Recommended Posts

À propos du comportement lors de la création d'un mappage de fichiers avec Java
Lorsqu'un fichier Java créé avec l'éditeur Atom est déformé lorsqu'il est exécuté à l'invite de commande
Une histoire sur l'utilisation de l'API League Of Legends avec JAVA
Créez un fichier jar avec la commande
[Java] Créez un fichier jar compressé et non compressé avec la commande jar
Lire une chaîne dans un fichier PDF avec Java
Une histoire sur le JDK à l'ère de Java 11
Histoire d'essayer de faire fonctionner le fichier JAVA
Créer une carte multi-touches avec une bibliothèque standard
À propos de la méthode cartographique
Vérifiez le comportement de Java Intrinsic Locks avec bpftrace
J'ai essayé OCR de traiter un fichier PDF avec Java
[Java] Lors de l'écriture du source ... Mémorandum ①
Une histoire sur le développement de ROS appelé rosjava avec java
Comment enregistrer des fichiers avec l'extension spécifiée sous le répertoire spécifié en Java dans la liste
Lors du téléchargement d'un fichier avec Spring Boot, la gestion des erreurs est effectuée lorsque la taille maximale du fichier est dépassée.
Remarques sur la portée
[Java] Créer un fichier temporaire
Erreur lors de la lecture avec java
J'ai essayé OCR de traiter un fichier PDF avec Java part2
Comment réduire même un peu la charge du programme lors de la combinaison de caractères avec JAVA
Comment gérer le type auquel j'ai pensé en écrivant un programme Java pendant 2 ans
Créez un serveur Web simple avec la bibliothèque standard Java com.sun.net.httpserver
À propos de ce que j'ai fait lors de la création d'un fichier .clj avec Clojure
Lisez le fichier sous le chemin de classe sous forme de chaîne de caractères avec ressort
Remplacer par une valeur selon la correspondance avec une expression régulière Java
Une histoire sur la difficulté à aligner un cadre de test avec Java 6
Le point addictif lors de l'authentification de base avec Java URLConnection
Écraser le téléchargement du fichier avec le même nom avec BOX SDK (java)
[Gradle] Construisez un projet Java avec une configuration différente de la convention
À propos du comportement de ruby Hash # ==
Construire un projet Java avec Gradle
En savoir plus sur les points de sauvegarde des transactions (avec Java)
Exécuter le fichier de commandes à partir de Java
Décompressez le fichier zip en Java
À propos de l'environnement de développement actuel (Java 8)
Créer une carte de liste avec LazyMap
Suivez le lien avec Selenium (Java)
Exemple de mise à jour de fichier EXCEL avec JAVA
A propos du traitement de la copie de fichiers en Java
Conversion de liste Java8 avec Stream map
[IntelliJ IDEA] Comment ajouter automatiquement la finale lors de l'enregistrement d'un fichier Java
L'histoire de l'oubli de fermer un fichier en Java et de l'échec
L'histoire de la création d'un lanceur de jeu avec une fonction de chargement automatique [Java]
Exprimons le résultat de l'analyse du code d'octet Java dans un diagramme de classes
Créez une carte du métro de Tokyo à partir du fichier CSV de la station data.jp
Mémo: [Java] Si un fichier se trouve dans le répertoire surveillé, traitez-le.
Comment savoir quelle version Java d'un fichier de classe a été compilée
[Petite histoire Java] Surveiller lorsqu'une valeur est ajoutée à la liste
Exemple de programme qui renvoie la valeur de hachage d'un fichier en Java
À propos de la spécification de la période de validité lors de l'enregistrement du cache dans Redis avec Spring Cache
<java> Fractionner l'adresse avant et après l'adresse avec une expression régulière
Décrypter le bean entier dans un fichier de propriétés avec certaines valeurs cryptées
[Java] Récupère MimeType à partir du contenu du fichier avec Apathce Tika [Kotlin]
A propos du renvoi d'une référence dans un Java Getter
Lors de la recherche de plusieurs dans un tableau Java