2009-02-26 6 views
6

J'ai besoin d'allouer de grands blocs de mémoire avec du nouveau.Allocation de grands blocs de mémoire avec nouveau

Je suis coincé avec l'utilisation de nouveaux parce que je suis en train d'écrire un faux pour le côté producteur d'une application en deux parties. Le code producteur réel alloue ces gros blocs et mon code a la responsabilité de les supprimer (après les avoir traités).

Y a-t-il un moyen de s'assurer que mon application est capable d'allouer une telle quantité de mémoire à partir du tas? Puis-je définir le tas à une taille plus grande?

Mon cas est de 64 blocs de 288000 octets. Parfois, je suis en train d'allouer des tâches et d'autres fois je vais les répartir. J'obtiens une exception std :: bad_alloc. Il s'agit de: C++, GCC sous Linux (32 bits).

+0

Avez-vous besoin de tout cela en une seule fois? Sinon, vous pouvez utiliser un pool de mémoire et un allocateur personnalisé pour gérer le pool. – dirkgently

+0

Comme je l'ai dit, j'essaie de me moquer de ce que le code producteur va faire. J'utiliserais un pool de mémoire alloué statiquement si je le pouvais. – JeffV

+0

Vous pouvez utiliser un pool alloué statiquement et remplacer vos appels par delete avec une fonction 'FreeBlock'. De cette façon, vous pouvez vérifier que vous avez rempli chaque bloc acquis. –

Répondre

9

En ce qui concerne nouveau en C++/GCC/Linux (32 bits) ...

Il a été un certain temps, et il est dépendant de la mise en œuvre, mais je crois nouvelle sera, dans les coulisses, appelez malloc(). Malloc(), sauf si vous demandez quelque chose dépassant l'espace d'adressage du processus, ou en dehors des limites spécifiées (ulimit/getrusage), n'échouera pas. Même lorsque votre système n'a pas assez de RAM + SWAP. Par exemple: malloc (1gig) sur un système avec 256 Mo de RAM + 0 SWAP, je crois, réussir. Cependant, lorsque vous utilisez cette mémoire, le noyau fournit les pages via un mécanisme d'allocation différée. À ce stade, lorsque vous lisez ou écrivez d'abord dans cette mémoire, si le noyau ne peut pas allouer de pages de mémoire à votre processus, il tue votre processus.

Cela peut être un problème sur un ordinateur partagé, lorsque votre collègue a une fuite de base lente. Surtout quand il commence à assommer les processus du système. Par conséquent, le fait que vous voyiez des exceptions std :: bad_alloc est «intéressant».

Maintenant nouveau exécutera le constructeur sur la mémoire allouée, en touchant toutes ces pages de mémoire avant son retour. En fonction de la mise en œuvre, il pourrait piéger le signal de mémoire insuffisante.

Avez-vous essayé ceci avec plain o'l malloc?

Avez-vous essayé d'exécuter le programme "free"? Avez-vous assez de mémoire disponible?

Comme d'autres l'ont suggéré, avez-vous vérifié limit/ulimit/getrusage() pour dur & contraintes molles?

À quoi ressemble votre code, exactement? Je devine nouveau ClassFoo [N]. Ou peut-être nouveau char [N].

Qu'est-ce que sizeof (ClassFoo)? Qu'est-ce que N?

L'allocation de 64 * 288000 (17.58Meg) devrait être triviale pour la plupart des machines modernes ... Utilisez-vous un système embarqué ou quelque chose d'autre spécial?

Vous pouvez également créer un lien avec un nouveau allocataire personnalisé? Votre classe a-t-elle son propre nouvel allocateur?

Votre structure de données (classe) alloue-t-elle d'autres objets dans le cadre de son constructeur?

Est-ce que quelqu'un a trafiqué vos bibliothèques? Avez-vous plusieurs compilateurs installés? Utilisez-vous les mauvais chemins d'inclusion ou de bibliothèque?

Liez-vous des fichiers objets périmés? Avez-vous simplement besoin de recompiler tous vos fichiers sources? Pouvez-vous créer un programme de test trivial? Juste quelques lignes de code qui reproduisent le bug? Ou est-ce que votre problème est ailleurs et ne se manifeste que là?

-

Pour ce que ça vaut, je l'ai réparti sur des blocs de données 2gig avec nouvelle dans linux 32 bits sous g ++. Votre problème est ailleurs.

+1

+1 pour la ventilation complète! – JeffV

4

Il est possible que vous soyez limité par le processus 'ulimit; exécutez ulimit -a et vérifiez la mémoire virale et les limites de taille de segment de données. Sinon, pouvez-vous poster votre code d'allocation afin que nous puissions voir ce qui se passe réellement?

+0

J'ai vérifié en utilisant getrlimit (RLIMIT_AS, & lim), il rapporte 4Go sur courant et max. – JeffV

+0

@Jeff: Vous essayez seulement d'allouer environ 18Mb! C'est une pitance sur n'importe quel ordinateur moderne. Il doit y avoir quelque chose d'autre allouer des tonnes de mémoire dans votre programme. –

0

Je suggérerais d'allouer toute votre mémoire au démarrage du programme et d'utiliser de nouveaux emplacements pour positionner vos tampons. pourquoi cette approche? Eh bien, vous pouvez garder une trace de la fragmentation et ainsi de suite. il n'y a pas de façon portable de déterminer combien de mémoire peut être allouée à votre processus. Je suis certain qu'il y a un appel système spécifique à Linux qui vous donnera cette information (je ne peux pas penser à ce que c'est). bonne chance.

0

Le fait que vous obteniez un comportement différent lorsque vous exécutez le programme à des moments différents me fait penser que le code d'allocation n'est pas le vrai problème. Au lieu de cela, quelqu'un d'autre utilise la mémoire et vous êtes le canari découvrant que c'est manquant.

Si "quelqu'un d'autre" se trouve dans votre programme, vous devriez pouvoir le trouver en utilisant Valgrind. Si cette personne est un autre programme, vous devriez être capable de le déterminer en vous rendant dans un autre programme (bien que vous ne connaissiez pas nécessairement le coupable).

1

Mise à jour:

J'ai depuis fixé un bug d'indexation de tableau et qu'elle affecte maintenant correctement.

Si je devais deviner ... Je marchais sur tout mon tas et jouais avec les structures de données du malloc. (??)

+0

Ce serait certainement le faire! Parfois, j'utilise des méthodes d'accès INLINED avec des instructions assert pour détecter de tels problèmes pendant la phase de débogage. (Ils sont compilés pour le code de production.) –