c ++ - allokere mere end 1 GB hukommelse på 32 bit XP

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg går ud over et ulige problem, min proces kan ikke allokere mere end hvad der synes at ligge lidt under 1 GiB. Windows Task Manager 'Mem Usage' -kolonnen viser værdier tæt på 1 GiB, når min software giver en bad\_alloc undtagelse. Ja, jeg 'v kontrollerede, at værdien, der er overført til hukommelsesallokering, er fornuftig. (ingen race betingelse/korruption eksisterer, der ville gøre dette mislykkes). Ja, jeg har brug for al denne hukommelse, og der er ingen vej rundt om det. (Det er en buffer til billeder, som ikke kan komprimeres yderligere)


Jeg forsøger ikke at allokere hele 1 GiB-hukommelsen på én gang, der er nogle tildelinger på omkring 300 MiB hver. Vil det medføre problemer? (Jeg vil forsøge at se, om flere mindre tildelinger fungerer bedre). Er der nogen compiler switch eller noget andet, som jeg skal indstille for at komme forbi 1 GiB? Jeg har set andre, der klager over grænsen på 2 GiB, hvilket ville være fint for mig. Jeg har bare brug for lidt mere :). Jeg bruger VS 2005 med SP1 og jeg kører det på en 32 bit XP og det 's i C ++.

Bedste reference


På en 32-bit OS har en proces et 4 GB adresserum i alt .


På Windows er halvdelen af ​​grænserne, så din proces har 2 GB.


Dette er 2 GB sammenhængende hukommelse. Men det bliver fragmenteret. Din eksekverbarhed er indlæst i en adresse, hver DLL er indlæst på en anden adresse, så er der stakken og høje tildelinger mv. Så mens din proces formentlig har nok ledigt adresserum, er der ingen sammenhængende blokke, der er store nok til at opfylde dine anmodninger om hukommelse. Så ved at lave mindre tildelinger vil det nok løse det.


Hvis din ansøgning kompileres med LARGEADDRESSAWARE-flag, vil det blive tilladt at bruge så meget af de resterende 2 GB, som Windows kan spare. (Og værdien af ​​det afhænger af din platform og dit miljø.



  • til 32-bit kode kører på et 64-bit OS, får du et fuldt 4-GB adresserum

  • til 32-bit kode kører på et 32-bit OS uden/3GB boot switch, betyder flaget slet ingenting

  • til 32-bit kode kører på et 32-bit OS med startknappen/3GB, får du 3 GB adresserum.



Så meget er det altid en god ide at sætte flagget, hvis din applikation kan håndtere det (det er i grunden et kapacitetsflag. Det fortæller Windows, at vi kan håndtere mere hukommelse, så hvis Windows kan også bør bare gå videre og give os så stor en adresseplads som muligt), men du kan nok ikke stole på, at det har en virkning. Medmindre du er på et 64-bit-operativsystem, er det usandsynligt at købe dig meget. (Startknappen/3GB er nødvendigt, og det har været kendt at forårsage problemer med drivere, især video drivere)

Andre referencer 1


At tildele store klumper af kontinuerlig hukommelse er altid et problem.
Det er meget sandsynligt at få mere hukommelse i mindre klumper


Du skal omstrukturere dine hukommelseskonstruktioner.

Andre referencer 2


Du har ret til at mistanke om de større 300 MB tildelinger. Din proces vil kunne nå tæt på 2 GB (3 hvis du bruger/3GB boot.ini switch og LARGEADDRESSAWARE link flag), men ikke som en stor sammenhængende blok.


Typiske løsninger til dette er at opdele anmodningerne i fliser eller strimler af fast størrelse (sige 256x256x4 bytes) og skrive en mellemklasse for at skjule denne repræsentationsdetalje.


Du kan hurtigt bekræfte dette ved at skrive en lille tildelingssløjfe, der tildeler blokke af forskellige størrelser.

Andre referencer 3


Du kan også tjekke denne funktion fra MSDN. 1GB ringer en klokke herfra: [2]



  Denne parameter skal være større end eller lig med 13 sider (for eksempel,
  53.248 på systemer med 4K sidestørrelse) og mindre end hele systemet
  maksimum (antal ledige sider minus 512 sider). Standardstørrelsen
  er 345 sider (for eksempel er dette 1.413.120 bytes på systemer med a
  4K sidestørrelse).



Her nævnte de, at standard maksimalt antal sider tilladt for en proces er 345 sider, hvilket er lidt mere end 1 GB.

Andre referencer 4


Når jeg har nogle store tildelinger sådan at gøre, bruger jeg Windows-funktionen VirtualAlloc for at undgå at understrege standardfordelingen.


En anden vej fremad kan være at bruge nedmalloc i dit projekt. [3]