De combien de mémoire devriez-vous être en mesure d'allouer?
Contexte: je suis en train d'écrire un programme C++ de travailler avec de grandes quantités de données, et souhaitez charger de gros morceaux de traiter d'un seul coup. Je suis contraint de travailler avec une application compilée en 32 bits machines. La machine que je suis en train de tester sur exécute une version 64 bits de l'OS (Windows 7) et a 6 gig de ram. À l'aide de MS VS 2008.
J'ai le code suivant:
byte* pTempBuffer2[3];
try
{
//size_t nBufSize = nBandBytes*m_nBandCount;
pTempBuffer2[0] = new byte[nBandBytes];
pTempBuffer2[1] = new byte[nBandBytes];
pTempBuffer2[2] = new byte[nBandBytes];
}
catch (std::bad_alloc)
{
//If we didn't get the memory just don't buffer and we will get data one
//piece at a time.
return;
}
J'espérais que je serais en mesure d'allouer de la mémoire jusqu'à ce que l'application a atteint la limite des 4 gigaoctets de 32 bits d'adressage. Toutefois, lorsque nBandBytes est 466,560,000 les nouveaux lancers std::bad_alloc sur le deuxième essai. À ce stade, l'ensemble de travail (de mémoire) de la valeur pour le processus est 665,232 K Donc, je ne semble pas être en mesure d'obtenir même un gig de mémoire allouée.
Il y a eu une mention d'un 2 go de limite pour les applications 32 bits de Windows qui peut être étendu à 3 concert avec le commutateur /3GB pour win32. Il est de bon conseil, en vertu de cet environnement, mais pas pour ce cas.
La quantité de mémoire que vous être en mesure d'allouer en vertu de la 64 bits de l'OS avec un 32 bits?
Sur ma machine 32 bits, je suis en mesure d'allouer 466,560,000×3 octets de test simple. Semblent être la mémoire de processus déjà fragmentée à l'allocation point dans votre cas.
J'ai eu un moment difficile de la sélection d'une réponse à la marque correcte sur cette question. Je crois que la réponse est complexe et dépend de nombreux facteurs. Les fichiers mappés en mémoire sont une bonne réponse, mais la cause de ce problème semble être une fragmentation de la mémoire. bke1 a souligné les bons outils pour la recherche sur la mémoire, et beaucoup de personnes ont parlé de la fragmentation de la mémoire, mais je l'ai choisi la première réponse qui indiquaient clairement le problème et a donné des limites dures (4 Gig de moins de 64 bits et le droit des drapeaux.)
Merci à tous, et merci en particulier pour les liens vers des articles très.
D'autres tests révèle ceci: j'ai essayé d'allouer de la ram dans de 3000 morceaux, et il a échoué à environ 95% du chemin. Beaucoup plus proche de l'achèvement de le faire en 3 morceaux, mais toujours pas de chance. Le VMMap outil signalé que j'avais 1.4 Gig d'espace libre, mais encore dans de 3000 morceaux, je ne pouvais pas affecter 1,3 Concert. Aller de l'avant sur ce problème, je vais essayer les fichiers mappés en mémoire.
OriginalL'auteur Bill | 2009-06-23
Vous devez vous connecter pour publier un commentaire.
Autant que l'OS veut vous donner. Par défaut, Windows permet à un processus 32 bits ont 2 GO d'espace d'adressage. Et cela est divisé en plusieurs morceaux. Une zone est réservée pour la pile, d'autres pour chaque exécutable et dll qui est chargée. Quelle que soit la gauche peut être alloué dynamiquement, mais il n'y a aucune garantie que ça va être un grand espace contigu. Il pourrait y avoir plusieurs petits morceaux de quelques centaines de MO.
Si vous compilez avec l'Option drapeau, 64-bit de Windows vous permet d'utiliser la totalité de l'espace d'adressage de 4 go, ce qui devrait aider un peu, mais en général,
Lodle, vous confondez l'adresse de l'espace libre et l'espace d'adresse. E. g. l'une des formes les plus courantes de la fragmentation causée par le code lui-même. Le fichier EXE et les DLL n'a pas la charge de départ à 0x00000000.
Nope, l'application voit une zone contiguë de l'espace d'adresse, mais le fichier exe, dll, la pile et les variables statiques sont tous chargés à différentes adresses au sein de cet espace d'adressage.
Continue de l'espace d'adressage est appelée Mémoire Virtuelle. Il y a un composant matériel, le Gestionnaire de Mémoire, droit à côté du processeur, qui convertit les adresses virtuelles en adresses physiques. Votre programme est compilé en code objet wrt un espace d'adressage virtuel.
OriginalL'auteur jalf
sur windows 32 bits, le processus peut prendre de 2 GO au maximum, mais avec Le commutateur /3GB interrupteur qu'il peut atteindre 3 GO (windows 2003).
mais dans votre cas, je pense que vous allouez de la mémoire contiguë, et si l'exception s'est produite.
Le commutateur /3GB est un peu dangereux. De nombreux conducteurs ne sont pas testé avec le commutateur, de sorte qu'ils peuvent devenir instable lorsque le système d'exploitation est limitée à 1 go. Il n'a pas d'importance si, comme il est en cours d'exécution sur un Windows 64 bits.
Pour m'aider à comprendre ce que vous rae dire, je vais essayer de la reformuler. Dites-vous que si j'alloue de la mémoire en blocs plus petits, je vais être en mesure d'obtenir plus de mémoire totale allouée?
C'est ce que j'ai dit! 😉
Probablement, oui. Si vous allouer des blocs de plus petite taille, ils n'ont pas à être contiguë, ce qui signifie qu'il est plus probable que le système d'exploitation sera en mesure de trouver de l'espace. Comme simple exemple, imaginez que votre application est chargée exactement au milieu de l'espace d'adressage. Ensuite, aucune distribution ne peut être plus grand que la moitié de l'espace d'adressage est effectivement réduit de moitié. Vous pouvez faire deux petites allocations, mais pas une seule grande. Maintenant, imaginez que vous avez une dizaine de morceaux placé tous sur la place, et l'espace est coupé même les plus petits.
OriginalL'auteur Ahmed Said
Vous pouvez allouer plus de mémoire que votre fichier de page permettra de vous - même sans le commutateur /3GB, vous pouvez allouer 4 go de mémoire, sans trop de difficulté.
Lire cet article pour avoir un bon aperçu de la façon de penser à propos de la mémoire physique, la mémoire virtuelle, et l'adresse de l'espace (tous les trois sont des choses différentes). En un mot, vous avez exactement comme la quantité de mémoire physique que vous avez de RAM, mais votre application n'a vraiment aucune interaction avec la mémoire physique à tous - c'est juste un endroit pratique pour stocker les données dans votre mémoire virtuelle. Votre mémoire virtuelle est limité par la taille de votre fichier d'échange, et le montant de votre application peut utiliser est limitée par la façon dont beaucoup d'autres applications sont à l'aide (bien que vous pouvez allouer plus, fournir vous n'avez pas réellement l'utiliser). Votre espace d'adressage de 32 bits monde est de 4 go. De ces, de 2 GO sont alloués au noyau (ou 1 go si vous utilisez le /3BG switch). De la de 2 go qui sont de gauche, de certains va être utilisé par votre pile, certains par le programme, vous êtes en cours d'exécution, (et toutes les dll, etc..). Ça va être fragmenté, et vous allez seulement d'être en mesure d'avoir autant d'espace contigu - c'est là que votre allocation est un échec. Mais depuis que l'espace d'adressage est juste un moyen pratique d'accéder à la mémoire virtuelle allouée pour vous, il est possible d'allouer beaucoup plus de mémoire, et d'apporter des morceaux de celui-ci dans votre espace d'adresse un peu à la fois.
Raymond Chen a un exemple de comment allouer de la mémoire de 4 go et la carte d'une partie d'une section de votre espace d'adressage.
Sous un Windows 32 bits, le maximum pouvant être affectés est de 16 to et 256TB en 64 bits de Windows.
Et si vous êtes vraiment dans la façon dont la gestion de la mémoire dans Windows, lire cet article.
OriginalL'auteur Eclipse
Au cours de la ElephantsDream projet de la Fondation Blender Blender 3D a eu des problèmes similaires (bien que sur Mac). Ne peut pas inclure le lien mais google: blender3d problème d'allocation de mémoire et il sera le premier élément.
La solution de Mappage de Fichier. N'ai pas essayé moi-même, mais vous pouvez la lire ici: http://msdn.microsoft.com/en-us/library/aa366556(SV.85).aspx
OriginalL'auteur tombjo
Avec nBandBytes à 466,560,000, en essayant de vous allouer 1,4 GO. Une application 32 bits en général seulement a accès à 2 GO de mémoire (plus si vous démarrez avec le commutateur /3GB et l'exécutable est marqué comme grand espace d'adressage courant). Vous avez peut-être du mal à trouver que plusieurs blocs contigus de l'espace d'adresse de votre gros morceaux de la mémoire.
Si vous souhaitez allouer des gigaoctets de mémoire sur un OS 64 bits, utiliser un processus 64 bits.
3 * 466,560,000 . Il est l'allocation de 3 tableaux.
Correct, j'espérais être en mesure d'allouer 1.3 giga-octets de mémoire, et a été surpris quand je ne pouvais pas.
RE: "grand espace d'adressage courant" le code est dans une .dll et l' .dll a été compilé avec le lare espace d'adressage courant des paramètres. L'ensemble de l'application doivent être marqués de cette façon, ou est-il OK juste pour le drapeau .dll?
le fichier exe a besoin d'être grand espace d'adressage courant
OriginalL'auteur Michael
Vous devriez être en mesure d'allouer un total d'environ 2 go par processus. Cet article (PDF) explique les détails. Toutefois, vous ne serez probablement pas en mesure d'obtenir d'un seul bloc contigu qui est encore proche de celle des grands.
OriginalL'auteur Naaff
Même si vous répartir en petits morceaux, vous ne pouviez pas obtenir la mémoire dont vous avez besoin, surtout si l'environnement programme a imprévisibles comportement de la mémoire, ou si vous avez besoin pour fonctionner sur différents systèmes d'exploitation. Dans mon expérience, le segment de l'espace sur un processus 32 bits casquettes à environ 1,2 GO.
À cette quantité de mémoire, je vous recommande manuellement l'écriture sur le disque. Enveloppez vos tableaux dans une classe qui gère la mémoire et l'écrit dans les fichiers temporaires lorsque cela est nécessaire. Nous espérons que les caractéristiques du programme sont tels qu'il pourrait effectivement s'en cache les parties de données sans toucher le disque de trop.
OriginalL'auteur Drew Hoskins
Sysinternals VMMap est idéal pour enquêter sur l'espace d'adressage virtuel de la fragmentation, qui est probablement la limitation de la mémoire contiguë vous pouvez allouer. Je vous invite à mettre à l'affichage de l'espace libre, puis tri par taille de trouver le plus grand des surfaces libres, ensuite le tri en fonction de l'adresse pour voir ce qui sépare le plus les zones libres (probablement relocalisée les Dll de la mémoire partagée des régions, ou des tas d'autres).
En évitant les très grandes contiguë allocations est probablement pour le mieux, comme d'autres l'ont suggéré.
Réglage
LARGE_ADDRESS_AWARE=YES
(comme jalf.com suggéré) est bon, aussi longtemps que les bibliothèques que votre application dépend sont compatibles avec elle. Si vous le faites, vous devez tester votre code avec leAllocationPreference
jeu de clés de registre pour activer le haut-vers le bas d'adressage virtuel d'allocation.OriginalL'auteur bk1e