Question

Je teste la taille d'une collection pourrait être en .Net. Techniquement, tout objet de collection pourrait pousse à la taille de la mémoire physique.

Alors j'ai testé le code suivant dans un sever, qui dispose d'une mémoire de 16 Go, serveur exécutant Windows 2003 et Visual Studio 2008. Je l'ai testé à la fois F # et C # code, et regarda le Gestionnaire des tâches lors de l'exécution. Je peux voir que, après sur la croissance de 2 Go de mémoire, le programme est écrasé à l'exception hors mémoire. Je ne mets la plate-forme cible à 64 bits dans la page de propriétés.

open System.Collections.Generic

let d = new Dictionary<int, int>()

for i=1 to 1000000000 do
    d.Add(i,i)

Je l'ai fait un même test à la bibliothèque de collection C5 . Le résultat est que le dictionnaire en C5 pourrait utiliser la mémoire entière. Le code utilise C5:

let d = C5.HashDictionary<int, int> ()
for i=1 to 1000000000 do
    d.Add(i,i)

Quelqu'un sait pourquoi?

Était-ce utile?

La solution

Le Microsoft CLR a une limite de taille de l'objet maximum de 2 Go, même la version 64 bits. (Je ne suis pas sûr que cette limite est également présent dans d'autres mises en œuvre telles que Mono.)

La limitation s'applique à chaque à objet - pas la taille totale de tous les objets -. Ce qui signifie qu'il est relativement facile à contourner en utilisant une collection composite de quelque sorte

Il y a une discussion et quelques exemples de code ici ...

Il semble y avoir très peu de documentation officielle qui fait référence à cette limite. Il est, après tout, un détail de mise en œuvre du CLR en cours. La seule mention que je connais est sur cette page :

  

Lorsque vous exécutez une gestion 64 bits   application sur un Windows 64 bits   système d'exploitation, vous pouvez créer un   objet de pas plus de 2 gigaoctets   (GB).

Autres conseils

Dans les versions de .NET avant 4.5, la taille de l'objet maximale est de 2 Go. si gcAllowVeryLargeObjects A partir de 4.5 partir, vous pouvez allouer des objets plus grands est activée. Notez que la limite pour string n'est pas affectée, mais « tableaux » devrait couvrir « listes » trop, car les listes sont soutenus par des réseaux.

Et pour être clair, un dictionnaire utilise un seul tableau pour ajouter les paires. Il est cultivé (doublé?) À chaque fois qu'il est plein. Quand il y a des objets 512 millions, sa taille est 2GByte (avec un pointeur d'objet 32 ??bits, et en supposant une distribution parfaite). Ajout d'un élément plus fait le dictionnaire essayer de doubler la taille du tableau à nouveau. Boom.

Le C5 HashDictionary utilise le hachage linéaire, et utilise probablement un ensemble de godets de chaque multiple contenant (16?) Des éléments. Il devrait fonctionner dans le même problème (beaucoup) plus tard.

Les « grands objets » permettent de ne feront que l'aide pour se débarrasser d'exception OOM.

Quand on a besoin de stocker de très nombreux objets le problème que vous verrez est stalles GC (pauses). Ce que nous avons fait est « caché » des données de GC, qui se transforma en une solution très pratique.

Voir ceci: https://www.infoq.com/articles/ Big-Memory-Part-3

Vous pouvez utiliser le cache qui fonctionne comme un dictionnaire: https://github.com/aumcode/nfx/tree/ maître / Source / NFX / ApplicationModel / Pile

voir la section de mise en cache

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top