You claim "my system with a 1TB disk and 8GB real memory allows allocating over 140TB of virtual memory." I can't replicate this.
On Windows 7, you can't allocate an array larger than the limit of the paging file allocation. Either you have a very large paging allocation, or you may have had a problem with the array size definition.
The following program runs with gFortran 6.2.0 on Windows 7 and demonstrates:
When allocating an array, the array size must be smaller than the available paging space. This allocation does not affect the physical memory allocation until the array is used (initialised)
When the new array size exceeds the available physical memory, then it is swapped to pagefile.sys, which appears as a system hang or crash. I have not bothered to wait for this to clear. ( We have short memories of the performance of old VAX/Pr1mos which ran from the paging file. )
Running the program and task manager appears to confirm the results.
Hopefully running the program will demonstrate these outcomes.
The results identify 3 memory sizes:
1) physical memory which is provided from a pool when arrays are used.
2) paging memory on pagefile.sys which defines a limit when allocating.
3) Virtual memory or Virtual addressing space or 8 terra bytes (2^43 bytes)
There is often confusion between successfully allocating an array (stat=0) and using the array when physical memory pages are allocated. If available physical memory is exceeded, everything appears to hang.
! Program to allocate a lot of memory to test allocate
use ISO_FORTRAN_ENV
integer*8 :: one_gig = 1024*1024*(1024/8) ! size of 1 gb array
integer*8 :: ipos
integer*8, allocatable :: array(:)
integer*4 :: igig, stat_a, stat_d
integer*4 :: max_gb_page = 32
integer*4 :: max_gb_phys = 6
!
write (*,*) 'Compiler Version :',Compiler_Version ()
write (*,*) 'Compiler Options :',Compiler_Options ()
!
! first try to allocate large arrays and see where ALLOCATE changes memory availability
do igig = 1,max_gb_page
ipos = igig * one_gig
allocate ( array(ipos), stat=stat_a )
call report_memory_usage (' allocate only')
if (stat_a /= 0) exit
deallocate ( array, stat=stat_d )
write (*,*) igig,' stat=',stat_a, stat_d, ipos
end do
write (*,*) igig,' stat=',stat_a, stat_d, ' FAIL'
!
! now try to allocate and use the large arrays and see where memory availability changes
do igig = 1,max_gb_phys
ipos = igig * one_gig
allocate ( array(ipos), stat=stat_a )
call report_memory_usage (' first allocate')
if (stat_a /= 0) exit
call use_array ( array, ipos )
call report_memory_usage (' then initialise')
deallocate ( array, stat=stat_d )
write (*,*) igig,' stat=',stat_a, stat_d, ipos
end do
write (*,*) igig,' stat=',stat_a, stat_d, ' FAIL'
!
end
subroutine use_array ( array, ipos )
integer*8 :: ipos, i
integer*8 :: array(ipos)
!
do i = 1,ipos
array(i) = ipos-i*2
end do
write (*,*) 'array initialised', ipos
end subroutine use_array
subroutine report_memory_usage (string)
use ISO_C_BINDING
integer, parameter :: knd = 8 ! 8 byte integer
interface
function GlobalMemoryStatusEx(tick8) bind(C, name="GlobalMemoryStatusEx")
use ISO_C_BINDING
!GCC$ ATTRIBUTES STDCALL :: GlobalMemoryStatusEx
logical(C_BOOL) GlobalMemoryStatusEx
integer(C_LONG_LONG) tick8(8)
end function GlobalMemoryStatusEx
end interface
!
type MEMORYSTATUSEX
sequence
integer dwLength
integer dwMemoryLoad
integer(knd) ullTotalPhys
integer(knd) ullAvailPhys
integer(knd) ullTotalPageFile
integer(knd) ullAvailPageFile
integer(knd) ullTotalVirtual
integer(knd) ullAvailVirtual
integer(knd) ullAvailExtendedVirtual
end type
type (MEMORYSTATUSEX) :: mdata
character string*(*)
!
integer*4 :: tick4(16)
integer*8 :: tick8(8)
equivalence (tick4,tick8)
integer(knd) :: lastAvailPhys = 0
real*8 gb
external gb
! mdata%dwLength = 64
tick4 = 0
tick4(1) = 64
if ( GlobalMemoryStatusEx (tick8) ) then
mdata%dwMemoryLoad = tick4(2)
mdata%ullTotalPhys = tick8(2)
mdata%ullAvailPhys = tick8(3)
mdata%ullTotalPageFile = tick8(4)
mdata%ullAvailPageFile = tick8(5)
mdata%ullTotalVirtual = tick8(6)
mdata%ullAvailVirtual = tick8(7)
mdata%ullAvailExtendedVirtual = tick8(8)
print *, " "
print *, " Memory Report ",string
print *, "Percentage of physical memory in use ", mdata%dwMemoryLoad, " %"
print 11, "Amount of actual physical memory ", gb(mdata%ullTotalPhys)
print 11, "Amount of physical memory available ", gb(mdata%ullAvailPhys)
print 11, "PageFile/Committed memory limit ", gb(mdata%ullTotalPageFile)
print 11, "Amount of memory current process can commit ", gb(mdata%ullAvailPageFile)
print 11, "Size of virtual address space ", gb(mdata%ullTotalVirtual)
print 11, "Amount of unreserved/uncommitted memory ", gb(mdata%ullAvailVirtual)
11 format(1x,a,f0.3,' gb')
else
print*,"Report Memory Failed ", string
end if
end subroutine report_memory_usage
real*8 function gb ( bytes )
integer*8 :: bytes
real*8 :: one_gb = 1024.*1024.*1024. ! size of 1 gb
gb = dble (bytes) / one_gb
end function gb
( I have adapted the program to gFortran from Silverfrost FTN95, so hopefully I have not introduced any errors. )