AvailableMemory()
Posted: Wed Sep 09, 2009 5:17 am
I have no idea what the Linux and MacOS equivalents are but I'm sure they exist.
PS! Reason for the Ex is due to the official MDSN stating that the non Ex might not be reliable on 4GB+ systems, so the Ex is preferred when available.
The reason I want this is that, at least on Windows Vista (Win7 and XP as well?) it is possible to allocate so much memory that the system basically locks up.
Take for example just moments ago here, I allocated about 8GB, but I only have 4GB physical memory. I have Vista x64, the compiled program was also x64. My page file is around 8GB.
The allocation went fine (4+8GB virtual mem I guess?), but when I was to use FillMemory() the system slowed to a crawl as Windows tried to page out ALL memory, including OS memory and some kernel memory.
It took several minutes too open Task manager, several minutes to select, several minutes to wait for the kill box, several minutes after confirming, several minutes for the system to get responsive again.
(For those unaware, the memory is reserved but not really allocated until it's first used. So just because the allocation went ok does not mean the system won't kneel when you start using that memory)
Ideally AllocateMemory() should have a Check parameter that defaults to true, but since there is no way to atomically check available mem and then allocate that's out of the question I guess.
But a AvailableMemory() makes sense, which reports the memory available for allocation that will not cause a major issue for the OS or other applications.
I'll definitely from now on use this when allocating very large or user defined memory sizes, because as I found out, even a triple core CPU with Vista x64 can be brought to it's knees, which surprised me, because with 3 cores, even if a program went into a death loop it's still have 2x33% cpu power, so opening task manager has never been an issue unlike on single core CPU's.
So if a AvailableMemory() is added to a future PureBasic release I'm sure more than just me would be very happy
Example implementation on windows:
PS! Reason for the Ex is due to the official MDSN stating that the non Ex might not be reliable on 4GB+ systems, so the Ex is preferred when available.
The reason I want this is that, at least on Windows Vista (Win7 and XP as well?) it is possible to allocate so much memory that the system basically locks up.
Take for example just moments ago here, I allocated about 8GB, but I only have 4GB physical memory. I have Vista x64, the compiled program was also x64. My page file is around 8GB.
The allocation went fine (4+8GB virtual mem I guess?), but when I was to use FillMemory() the system slowed to a crawl as Windows tried to page out ALL memory, including OS memory and some kernel memory.
It took several minutes too open Task manager, several minutes to select, several minutes to wait for the kill box, several minutes after confirming, several minutes for the system to get responsive again.
(For those unaware, the memory is reserved but not really allocated until it's first used. So just because the allocation went ok does not mean the system won't kneel when you start using that memory)
Ideally AllocateMemory() should have a Check parameter that defaults to true, but since there is no way to atomically check available mem and then allocate that's out of the question I guess.
But a AvailableMemory() makes sense, which reports the memory available for allocation that will not cause a major issue for the OS or other applications.
I'll definitely from now on use this when allocating very large or user defined memory sizes, because as I found out, even a triple core CPU with Vista x64 can be brought to it's knees, which surprised me, because with 3 cores, even if a program went into a death loop it's still have 2x33% cpu power, so opening task manager has never been an issue unlike on single core CPU's.
So if a AvailableMemory() is added to a future PureBasic release I'm sure more than just me would be very happy

Example implementation on windows:
Code: Select all
Procedure.q AvailableMemory()
Protected result.q,memorystatusex.MEMORYSTATUSEX,memorystatus.MEMORYSTATUS,*GlobalMemoryStatusEx,dll.i
dll=OpenLibrary(#PB_Any,"kernel32.dll")
If dll
*GlobalMemoryStatusEx=GetFunction(dll,"GlobalMemoryStatusEx")
EndIf
If *GlobalMemoryStatusEx
memorystatusex\dwLength=sizeof(MEMORYSTATUSEX)
CallFunctionFast(*GlobalMemoryStatusEx,memorystatusex)
result=memorystatusex\ullAvailPhys
Else
GlobalMemoryStatus_(memorystatus)
result=memorystatus\dwAvailPhys
EndIf
If dll
CloseLibrary(dll)
EndIf
ProcedureReturn result
EndProcedure