2010-04-19 6 views
3

Existe-t-il un moyen de dire à .NET d'allouer un nouvel objet dans la pile de génération 2? J'ai un problème où je dois allouer environ 200 Mo d'objets, faire quelque chose avec eux, et les jeter. Ce qui se passe ici, c'est que toutes les données sont copiées deux fois (de gen0 à gen1 puis de gen1 à gen2).Création et génération d'objets .NET

Répondre

0

Le cadre fonctionne différemment avec les grands objets qu'avec les objets normaux. Donc, brièvement, il met de gros objets dans la génération et ne le déplace pas lors de la réaffectation de tas.

2

Il n'y a aucun moyen d'allouer directement dans la génération 2. Toutes les allocations se produisent dans la génération 0 et pour les objets volumineux dans la LOH. Cependant, les données ne sont généralement pas copiées lorsque les objets passent à une nouvelle génération. Au lieu de cela, les points de départ des différents tas sont déplacés. Les objets peuvent être déplacés en raison du compactage du tas, mais c'est une histoire différente.

S'il est important de stocker des objets dans la génération 2, vous pouvez réutiliser les instances. C'est à dire. faites une méthode init sur les types et appelez ceci au lieu de créer de nouvelles instances.

+0

Si je comprends bien, tous les objets nouvellement créés sont attribués en tas Gen0. Quand gen0 heap est plein, tous les objets (qui sont encore nécessaires) sont déplacés vers gen1, et gen0 devient vide. La même chose arrive à gen1 quand GC de gen1 est exécuté. Autant que je sache, il n'y a pas une telle chose à déplacer des pointeurs vers différents tas. Peut-être que vous pouvez donner un lien vers MSDN ou quelque part, parce que ce que je vis est beaucoup de copie (qui peut être vu avec le moniteur de performance). – nimoraca

+0

@nimoraca: Le déplacement de la partie pointeur est ce que fait le CLR. Si ce n'est pas le cas, vous devrez déplacer des objets pour toutes les collectes, ce qui serait très inefficace. Consultez le livre CLR via C# pour plus de détails. Cet article a quelques-uns des mêmes points http://msdn.microsoft.com/en-us/magazine/bb985010.aspx –

+0

@ nimoraca: Si vous êtes intéressé par les détails, vous pouvez également inspecter les différents tas, etc en utilisant WinDbg et SOS (ou PSSCOR2). –

0

Si vous souhaitez corriger vos objets afin que l'infrastructure ne puisse pas les déplacer, vous pouvez essayer d'utiliser GCHandle pour épingler les objets. Ceci est généralement utilisé pour P/Invoke mais donnera le résultat que vous recherchez. J'ai des doutes que vous voyez des ralentissements dus à la compaction générationnelle mais je ne peux pas dire sans voir vos données de profilage.

http://msdn.microsoft.com/en-us/library/khk3k17t%28v=VS.71%29.aspx

Exemple:

var q = new MyObject(); 
var handle = GCHandle.Alloc(q, GCHandleType.Pinned); 

// use object 

handle.Free(); 
Questions connexes