2009-02-26 5 views
6

Ich habe die Notwendigkeit, große Speicherblöcke mit neuen zuzuteilen.Zuweisung großer Speicherblöcke mit neuen

Ich bin mit der Verwendung von neuen stecken, weil ich einen Mock für die Produzentenseite einer zweiteiligen Anwendung schreibe. Der eigentliche Producer-Code ordnet diese großen Blöcke zu und mein Code hat die Verantwortung, sie zu löschen (nach der Verarbeitung).

Gibt es einen Weg, kann ich sicherstellen, dass meine Anwendung eine so große Menge an Speicher aus dem Haufen zuweisen kann? Kann ich den Heap auf eine größere Größe setzen?

Mein Fall ist 64 Blöcke von 288000 Bytes. Manchmal bekomme ich 12 zuzuteilen und andere Male bekomme ich 27 zuzuteilen. Ich bekomme eine std :: bad_alloc Ausnahme.

Das ist: C++, GCC unter Linux (32bit).

+0

Benötigen Sie alles auf einmal? Andernfalls könnten Sie einen Speicherpool und einen benutzerdefinierten Zuordner verwenden, um den Pool zu verwalten. – dirkgently

+0

Wie gesagt, ich versuche zu verspotten, was der produzierende Code machen wird. Ich würde einen statisch zugewiesenen Speicherpool verwenden, wenn ich könnte. – JeffV

+0

Sie könnten einen statisch zugewiesenen Pool verwenden und Ihre zu löschenden Anrufe durch eine "FreeBlock" -Funktion ersetzen. Auf diese Weise können Sie überprüfen, ob Sie jeden erworbenen Block gefüllt haben. –

Antwort

9

Im Hinblick auf neue in C++/GCC/Linux (32 Bit) ...

Es ist eine Weile her, und es ist die Umsetzung abhängig, aber ich glaube neue wird, hinter den Kulissen, rufen malloc(). Malloc(), sofern Sie nicht nach etwas fragen, das den Adressraum des Prozesses überschreitet, oder außerhalb der angegebenen Grenzwerte (ulimit/getrusage) nicht fehlschlagen. Selbst wenn Ihr System nicht genug RAM + SWAP hat. Zum Beispiel: malloc (1gig) auf einem System mit 256 Meg RAM + 0 SWAP wird, glaube ich, gelingen.

Wenn Sie jedoch diesen Speicher verwenden, stellt der Kernel die Seiten über einen Mechanismus für die verzögerte Zuweisung bereit. An diesem Punkt, wenn Sie den Speicher zum ersten Mal lesen oder in diesen schreiben, wenn der Kernel dem Prozess keine Speicherseiten zuweisen kann, wird Ihr Prozess beendet.

Dies kann ein Problem auf einem gemeinsam genutzten Computer sein, wenn Ihr Kollege ein langsames Kernleck hat. Vor allem, wenn er damit beginnt, Systemprozesse auszulöschen.

Die Tatsache, dass Sie std :: bad_alloc Ausnahmen sehen, ist also "interessant".

Jetzt neue wird den Konstruktor auf dem zugewiesenen Speicher ausführen und alle diese Speicherseiten berühren, bevor es zurückkehrt. Je nach Implementierung kann das Out-of-Memory-Signal abfangen.

Haben Sie das mit blanko malloc versucht?

Haben Sie versucht, das Programm "frei" auszuführen? Hast du genug Speicher zur Verfügung?

Wie andere vorgeschlagen haben, haben Sie limit/ulimit/getrusage() für hart & soft constraints?

Wie sieht Ihr Code genau aus? Ich schätze neue ClassFoo [N]. Oder vielleicht neue Kohle [N].

Was ist sizeof (ClassFoo)? Was ist N?

Zuordnung von 64 * 288000 (17.58Meg) sollte für die meisten modernen Maschinen trivial sein ... Laufen Sie auf einem Embedded-System oder etwas anderes Besonderes?

Verknüpfen Sie alternativ mit einem benutzerdefinierten neuen Zuordner? Hat Ihre Klasse einen eigenen neuen Allokator?

Ordnet Ihre Datenstruktur (Klasse) andere Objekte als Teil ihres Konstruktors zu?

Hat jemand Ihre Bibliotheken manipuliert? Haben Sie mehrere Compiler installiert? Verwenden Sie die falschen Include- oder Bibliothekspfade?

Verlinken Sie gegen veraltete Objektdateien? Müssen Sie einfach alle Ihre Quelldateien neu kompilieren?

Können Sie ein triviales Testprogramm erstellen? Nur ein paar Zeilen Code, der den Fehler reproduziert? Oder ist dein Problem anderswo und nur hier auftauchen?

-

Für das, was es wert ist, ich über 2gig Datenblöcke zugewiesen haben mit neuen in 32-Bit-Linux unter g ++. Dein Problem liegt woanders.

+1

+1 für den gründlichen Abbau! – JeffV

4

Es ist möglich, dass Sie durch den Prozess begrenzt werden 'ulimit; Führen Sie ulimit -a aus und überprüfen Sie die Größenbeschränkungen für virtuellen Speicher und Datensegmente. Oder können Sie Ihren Zuweisungscode posten, damit wir sehen können, was eigentlich passiert?

+0

Ich überprüfte mit gerlimit (RLIMIT_AS, & lim), es meldet 4GB auf aktuelle und max. – JeffV

+0

@Jeff: Sie versuchen nur etwa 18 MB zu reservieren! Das ist ein Hungerlohn auf jedem modernen Computer. Es muss etwas anderes sein, das Tonnen von Speicher innerhalb Ihres Programms zuweist. –

0

Ich würde vorschlagen, all Ihren Speicher beim Programmstart und mit Placement neu zu reservieren, um Ihre Puffer zu positionieren. Warum dieser Ansatz? Nun, Sie können manuell die Fragmentierung und so weiter verfolgen. Es gibt keinen tragbaren Weg zu bestimmen, wie viel Speicher für Ihren Prozess zugewiesen werden kann. Ich bin sicher, dass es einen Linux-spezifischen Systemaufruf gibt, der Ihnen diese Information bringen wird (kann nicht daran denken, was es ist). Viel Glück.

0

Die Tatsache, dass Sie unterschiedliche Verhalten erhalten, wenn Sie das Programm zu verschiedenen Zeiten ausführen, lässt mich denken, dass der Zuordnungscode nicht das eigentliche Problem ist. Stattdessen benutzt jemand anderes die Erinnerung und du bist der Kanarienvogel, der herausfindet, dass es fehlt.

Wenn diese "jemand anderen" in Ihrem Programm ist, sollten Sie in der Lage sein, es zu finden, indem Sie Valgrind verwenden.

Wenn dieser jemand anderes ein anderes Programm ist, sollten Sie in der Lage sein, das zu bestimmen, indem Sie zu einem anderen runlevel gehen (obwohl Sie den Täter nicht unbedingt kennen).

1

Update:

Ich habe ein Array Indizierung Fehler, da festgelegt und es wird jetzt richtig zugeordnet werden.

Wenn ich raten musste ... Ich lief überall auf meinem Haufen und beschäftigte mich mit den Datenstrukturen des Mallocs. (??)

+0

Das würde es sicherlich tun! Manchmal benutze ich INLINED-Zugriffsmethoden mit assert-Anweisungen, um solche Probleme während der Debugging-Phase aufzugreifen. (Sie werden für den Produktionscode kompiliert.) –

Verwandte Themen