9
votes

Dossier en streaming en Java

Je développe actuellement une application graphique 3D en utilisant jogl fort> (java OpenGL liant). En bref, j'ai un énorme fichier binaire paysager. En raison de sa taille, je dois diffuser des morceaux de terrain dans le temps d'exécution. Par conséquent, nous voyons explicitement la préoccupation d'accès aléatoire. J'ai déjà terminé la première mise en œuvre (et sale :)) (peut-être qu'il est multi-fileté), où j'utilise une approche insensée ... Voici l'initialisation de celui-ci:

dataInputStream.reset();
dataInputStream.skipBytes(offset);
dataInputStream.read(whatever I need...);


0 commentaires

3 Réponses :


2
votes

Pour un fichier de 220 Mo, je voudrais une carte la mémoire en mémoire dans la mémoire virtuelle. La raison fbm est si rapide est-ce que cela ne lit pas réellement les données en mémoire, elle le rend simplement disponible.

Remarque: lorsque vous exécutez le test, vous devez comparer comme pour comme si c'est-à-dire. Lorsque le fichier est dans le cache du système d'exploitation, il sera beaucoup plus rapide, peu importe la façon dont vous le faites. Vous devez répéter le test plusieurs fois pour obtenir un résultat capable de reproduire.


5 commentaires

Qu'entendez-vous par "disponible"? Il ne peut y avoir que 2 options: le fichier est complètement copié sur le mappebytebuffer (la taille maximale est de 2 Go pour les systèmes 32 bits) ou mappébytebuffer vient d'émuler ce fichier à l'aide de la mémoire tampon d'arrière-plan, de prédire la logique ou autre que j'ai essayé de mapper 1 Go Fichier et il n'a pas réussi à le faire, je dois conclure que sa cartographie semble copier le fichier entier sur mappébytebuffer ... ou est-ce que je me trompe toujours? S'il vous plaît soyez plus détaillé dans vos réponses.


Lors du mappage, le système d'exploitation plante le fichier en mémoire virtuelle. Les pages (généralement 4 Ko) du fichier sont amenées en mémoire lorsque vous les écrivez / écrivez et revenez lentement sur le disque. (Ou lorsque vous forcez une rinçage), vous ne pouvez pas lire un fichier de 220 Mo en mémoire en 0.2 secondes. Je ne sais pas pourquoi un fichier de 1 Go n'a pas été mappé que si vous utilisez un JVM 32 bits.


Oui, j'utilise JVM 32 bits, donc je ne comprends pas pourquoi la cartographie de fichier 1 Go échoue ... des idées? Actuellement, je ne m'intéresse qu'en lecture, donc je n'ai pas besoin de rinçage et etc. Vous venez de dire que le système d'exploitation chargait des pages de 4 Ko à la mémoire virtuelle, mais vous voyez que c'est ce que j'ai déjà dit, i. e. MappedBytebuffer vient d'émuler ce fichier en utilisant une logique tampon de fond lente, que je ne peux pas contrôler. Droit?


Un JVM 32 bits dans un système d'exploitation 32 bits ne peut utiliser qu'environ 1,2 à 1,5 Go de mémoire virtuelle. Un JVM 32 bits sur un système d'exploitation 64 bits peut accéder davantage. Sur Solaris, il peut accéder à 3,5 Go. Le plus grand JVM 64 bits JVM J'ai SEENC un accès 768 GB. Ni ne correspond à la limite théorique mais vous pouvez voir qu'un JVM 64 bits est le bon outil pour le travail. Vous pouvez contrôler l'endroit où vous accédez au fichier dans quel ordre, le montant du fichier que vous pouvez avoir en mémoire est limité par votre matériel, la vitesse qu'il peut lire que le fichier est également limité par votre matériel.


Java utilise la cartographie du système d'exploitation sous-jacente. Cela dit comment cela le fait car cela dépend du système d'exploitation que vous utilisez. Si vous voulez savoir comment votre système d'exploitation, vous devez lire la documentation pour votre système d'exploitation.



3
votes

Non, les données ne sont pas tamponnées. Un mappebytebuffer références les données utilisant un pointeur . En d'autres termes, les données ne sont pas copiées, il est simplement mappé dans la mémoire physique. Voir le API Docs si vous n'avez pas fait Déjà.

Un fichier mapé de mémoire est un segment de mémoire virtuelle qui a été attribuée une corrélation directe de l'octet d'octet avec une partie d'un fichier ou ressource semblable au fichier. Cette ressource est typiquement un fichier physiquement présent sur disque, mais peut aussi être un Dispositif, objet de mémoire partagé ou autre ressource que le système d'exploitation peut Référence via un descripteur de fichier. Une fois présent, cette corrélation entre Le fichier et l'espace mémoire permettent Applications pour traiter les mappés partie comme s'il s'agissait de la mémoire principale.

Source: Wikipedia

Si vous allez lire des données assez fréquemment, c'est une bonne idée de mettre au moins en cache une partie de celle-ci.


7 commentaires

Si vous dites que mappébytebuffer est un pointeur en HD, alors comment cela atteint-il de si bons résultats dans l'analyse comparative? La seule fonctionnalité de vitesse possible dans IO que je connais personnellement est d'accéder au disque aussi moins que possible et la seule solution ici est la mémoire tampon. Encore une fois, si vous êtes assez alphabétisé sur cette préoccupation, veuillez être plus détaillée.


@Haroogan je cite de cet article: "La différence est presque entièrement due aux commutateurs contextuels du noyau"


Vous devez être plaisant en me référant à Javadoc, n'est-ce pas? Coz, il n'y a pas d'informations particulières que je demande. Je n'ai toujours pas de réponses directes ni d'idées et de commentaires appropriés sur des solutions possibles.


@Haroogan Tout d'abord, ouvrez vos yeux. Ma réponse est suffisante, compte tenu de tout ce que vous vouliez savoir si "cartographie copie un fichier". La toute première ligne du Javadoc dit que les données sont mappées sur la mémoire. Vous auriez dû me demander ce que cela signifiait au lieu d'appeler ma réponse à une blague. Le reste de ma réponse expose sur ce que c'est, de toute façon. De plus, j'ai donné une suggestion supplémentaire sur la manière d'optimiser.


On dirait que tu ne l'obtiens pas. Je vais essayer à nouveau avec une question primitive. Il suffit de dire oui ou non. Si je mappe 1GB Fichier, mappebytebuffer capacité = 1 Go, la mappebytebuffer occupe donc-t-elle vraiment 1 Go de RAM ou il l'émule simplement?


Ma propre expérience me dit qu'il tente d'occuper 1 Go de mémoire RAM, car je ne suis pas capable de mapper 1 Go de fichier avec: "Hors de la mémoire: panne de la carte" Exception! Si je me trompe, arrêtez-moi, arrêtez-moi de me référencer à des documents inutiles, tous ces mots des Javadocs ne sont pas sauvegardés avec suffisamment d'informations. De plus, Javadocs est juste une aide rapide, pour vous parler de la bonne utilisation de la classe en Java, mais ce n'est pas un guide qui vous explique ce qui se passe dans les coulisses! Le mot cartographie des Javadocs me ne me dit rien de son mécanisme de vie réelle. J'espère que tu l'as eu maintenant.


@Haroogan je l'obtiens, c'est juste que je voulais m'assurer que vous avez compris les concepts. Il est difficile de répondre à votre question avec un "oui" ou "non", alors je vais vous lier à cet article: EN.WIKIPEDIA.ORG/WIKI/MEMORY-MAPPAW_FILE . Il est détaillé et aborde également pourquoi vous avez une exception hors mémoire.



1
votes

Avez-vous remarqué que si vous exécutez un programme, puis le fermez, puis courez-le, il démarre beaucoup plus vite que la deuxième fois? Cela se produit car le système d'exploitation a mis en cache les parties des fichiers qui ont été accessibles lors de la première exécution et n'ont pas besoin d'accéder au disque pour eux. Mémoire Mappage d'un fichier permet essentiellement à un programme d'accès à ces tampons, minimisant ainsi des copies effectuées lors de la lecture. Notez que la mappage de la mémoire d'un fichier ne le fait pas de lire tout en mémoire; Les bits et les morceaux que vous lisez sont lus à la demande du disque. Si l'OS détermine qu'il y a une mémoire faible, il peut décider de libérer certaines parties du fichier mappé de la mémoire et de les laisser sur disque.

EDIT: Ce que vous voulez, c'est fileInputtream.getchannel (). mappe () , puis adaptez-le à un INTERPREAM , puis connectez-le au DataGuTStream < / code>.


0 commentaires