Speicher reservieren



  • Hallo, kann mir jemand sagen was der Unterschied zwischen normaler Speicheranforderung mit new und der WinApi Funktion VirtualAlloc() ist?



  • VirtualAlloc reserviert Speicher in grossen Stücken (üblicherweise 64KB, wobei Windows theoretisch bis auf die Seitengrösse, also 4KB, runtergehen könnte), und committed Seitenweise (also 4KB).
    new dagegen ist ein C++ Sprachkonstrukt und erzeugt & initialisiert Objekte.

    D.h. du kannst mit VirtualAlloc nur "rohen" Speicher anfordern, mit "new" dagegen kannst du Objekte erzeugen. Und selbst wenn du "new" nur verwendest um ein char-Array zu erzeugen (="rohen Speicher anfordern"), wird "new" weniger Platz verschwenden (da es nicht auf Seitengrenzen aufrunden muss), und üblicherweise auch (viel) schneller sein.



  • hustbaer schrieb:

    ..., wird "new" weniger Platz verschwenden (da es nicht auf Seitengrenzen aufrunden muss), und üblicherweise auch (viel) schneller sein.

    Kannst Du beweisen das new schneller ist? Wenn ja wieviel ?

    Also letztenendes muss auch new mit einem Systemaufruf Speicher beim
    Betriebssystem anfordern und ihn dann auch noch initialisieren und verwalten ...

    Das VirtualAlloc eine Seiten Granularität verwendet ist natürlich zu bedenken,
    aber man könnte sicher auch andere Systemaufrufe nutzen.

    Microsoft sagt, das globale Funktionen wie GlobalAlloc() einen groesseren
    Overhead haben und Heap-Funktionen wie HeapAlloc() besser wären.

    Ich habe mich allerdings nicht mit Performancetests im Detail beschäftigt ...

    Bei Microsoft findet sich "Comparing Memory Allocation Methods"

    http://msdn.microsoft.com/en-us/library/windows/desktop/aa366533(v=vs.85).aspx

    für alle die das Thema interessiert.

    Und im Forum war das auch schon Thema; z.B. hier:
    http://www.c-plusplus.net/forum/300017-full



  • merano schrieb:

    Also letztenendes muss auch new mit einem Systemaufruf Speicher beim
    Betriebssystem anfordern und ihn dann auch noch initialisieren und verwalten ...

    Muss es nicht unbedingt. Es kann auch einmal 1MB anfordern und die vielen new's die ein paar Byte anfordern damit bedienen. Das heißt du alloziierst Speicher ohne Betriebssystem. So ein Systemcall kostet ~1300 CPU-Zyklen Overhead (nur für die Privilegiensprünge) habe ich mal gehört, da kann man mit ein bisschen Code von new leicht besser sein.

    merano schrieb:

    Das VirtualAlloc eine Seiten Granularität verwendet ist natürlich zu bedenken,
    aber man könnte sicher auch andere Systemaufrufe nutzen.

    Die Granularität hat sich nicht Microsoft sondern Intel ausgedacht. Sie ist in der x86er Architektur drin und nur mit den Inteleinstellungen (1, 2, 4kb?) kann man Speicherschutz bauen. Deshalb gibts leider üblicherweise auch keinen Segfault wenn man sein 3 Byte Array um ein paar Bytes zu viel beschreibt, das kriegt die MMU nicht mit.



  • merano schrieb:

    hustbaer schrieb:

    ..., wird "new" weniger Platz verschwenden (da es nicht auf Seitengrenzen aufrunden muss), und üblicherweise auch (viel) schneller sein.

    Kannst Du beweisen das new schneller ist?

    Ich könnte jetzt ne Benchmark schreiben, ist mir aber ehrlich gesagt zu doof. Es ist so, da gibt's nix grossartig zu überlegen.

    Wenn ja wieviel ?

    Probierst es aus, dann weisst du es. Bei kleinen Allokationen vermutlich irgendwo zwischen Faktor 10 und 100. Bei grossen Allokationen wird der Unterschied natürlich immer kleiner werden.

    Also letztenendes muss auch new mit einem Systemaufruf Speicher beim
    Betriebssystem anfordern und ihn dann auch noch initialisieren und verwalten ...

    Und? Macht ja nix.

    Das VirtualAlloc eine Seiten Granularität verwendet ist natürlich zu bedenken,
    aber man könnte sicher auch andere Systemaufrufe nutzen.

    Microsoft sagt, das globale Funktionen wie GlobalAlloc() einen groesseren
    Overhead haben und Heap-Funktionen wie HeapAlloc() besser wären.

    Mir ist ehrlich gesagt Wurst was MS in dem Artikel da schreibt, der glänzt nicht gerade vor Einsicht.
    malloc/new/HeapAlloc vs. VirtualAlloc das sind zwei ganz andere paar Schuhe.
    Sie in einem Artikel nebeneinanderzustellen, ohne die grundlegenden Unterschiede ausreichend zu erklären ist schon etwas komisch.

    MSVC verwendet übrigens per Default (ab Version 6 oder so) HeapAlloc() für new.



  • ps: hab nen Fehler in meinem ersten Beitrag korrigiert: die Granularität von VirtualAlloc ist bei Windows üblicherweise 64KB, nicht 4KB.





  • Sorry aber ich hab immer noch nicht verstanden warum manchmal z.B bei einem Dll-Injector VirtualAlloc() anstatt new oder malloc() verwendet wird.



  • Weil new/malloc nur im _eigenen_ Prozess Speicher allokieren können...



  • Ah ok DANKE!


Anmelden zum Antworten