Memory 如何让我的Fortran程序使用一定数量的RAM?

Memory 如何让我的Fortran程序使用一定数量的RAM?,memory,memory-management,fortran,Memory,Memory Management,Fortran,我正在尝试编写一个Fortran程序,它将消耗大量内存(关于这背后的原因,请参阅问题末尾的注释)。我这样做是通过分配一个大小为(n,n,n)的三维数组,然后取消分配它-不断增加n,直到我的内存用完为止(当使用约16 GB内存时,应该会发生这种情况)。不幸的是,在我看到系统资源达到16GB之前,我的程序似乎已经耗尽了内存 以下是我的示例代码: 1 program fill_mem 2 implicit none 3 integer, parameter :: ikind = sele

我正在尝试编写一个Fortran程序,它将消耗大量内存(关于这背后的原因,请参阅问题末尾的注释)。我这样做是通过分配一个大小为
(n,n,n)
的三维数组,然后取消分配它-不断增加
n
,直到我的内存用完为止(当使用约16 GB内存时,应该会发生这种情况)。不幸的是,在我看到系统资源达到16GB之前,我的程序似乎已经耗尽了内存

以下是我的示例代码:

 1 program fill_mem
 2   implicit none
 3   integer, parameter :: ikind = selected_int_kind(8)
 4   integer, parameter :: rkind = 8
 5
 6   integer(kind = ikind) :: nfiles = 100
 7   integer(kind = ikind) :: n = 1200
 8   integer(kind = ikind) :: i, nn
 9
10   real(kind = rkind), allocatable :: real_arr(:,:,:)
11
12   character(500) :: sysline
13
14
15   call system('echo ''***no_allocation***'' > outfile')
16   call system('ps aux | grep fill_mem.exe >> outfile')
17   !call system('smem | grep fill_mem.exe >> sm.out')
18   allocate(real_arr(n, n, n))
19
20   nn = 100000
21   do i = 1,nn
22     deallocate(real_arr)
23     n = n + 10
24     print*, 'n = ', n
25     allocate(real_arr(n, n, n))
26     call system('echo ''*************'' >> outfile')
27     write(sysline, *) 'allocation', i, '... n = ', n
28
29     write(*, '(f10.5, a)') 100.0*real(i)/real(nn), '%'
30
31     call system(trim(adjustl('echo '//sysline//'>> outfile')))
32     call system('ps aux | grep fill_mem.exe >> outfile')
33   enddo
34
35 end program fill_mem
下面是示例输出:

 1 ***no_allocation***
 2 1000     12350  0.0  0.0  12780   760 pts/1    S+   13:32   0:00 ./fill_mem.exe
 3 1000     12352  0.0  0.0   4400   616 pts/1    S+   13:32   0:00 sh -c ps aux | grep fill_mem.exe >> outfile
 4 1000     12354  0.0  0.0   9384   920 pts/1    S+   13:32   0:00 grep fill_mem.exe
 5 *************
 6 allocation 1 ... n = 1210
 7 1000     12350  0.0  0.0 13853104 796 pts/1    S+   13:32   0:00 ./fill_mem.exe
 8 1000     12357  0.0  0.0   4400   616 pts/1    S+   13:32   0:00 sh -c ps aux | grep fill_mem.exe >> outfile
 9 1000     12359  0.0  0.0   9384   920 pts/1    S+   13:32   0:00 grep fill_mem.exe
10 *************
11 allocation 2 ... n = 1220
12 1000     12350  0.0  0.0 14199096 952 pts/1    S+   13:32   0:00 ./fill_mem.exe
13 1000     12362  0.0  0.0   4400   612 pts/1    S+   13:32   0:00 sh -c ps aux | grep fill_mem.exe >> outfile
14 1000     12364  0.0  0.0   9384   920 pts/1    S+   13:32   0:00 grep fill_mem.exe
15 *************
16 allocation 3 ... n = 1230
17 1000     12350  0.0  0.0 14550804 956 pts/1    S+   13:32   0:00 ./fill_mem.exe
18 1000     12367  0.0  0.0   4400   612 pts/1    S+   13:32   0:00 sh -c ps aux | grep fill_mem.exe >> outfile
19 1000     12369  0.0  0.0   9384   920 pts/1    S+   13:32   0:00 grep fill_mem.exe
20 *************
21 allocation 4 ... n = 1240
22 1000     12350  0.0  0.0 14908284 956 pts/1    S+   13:32   0:00 ./fill_mem.exe
23 1000     12372  0.0  0.0   4400   612 pts/1    S+   13:32   0:00 sh -c ps aux | grep fill_mem.exe >> outfile
24 1000     12374  0.0  0.0   9384   920 pts/1    S+   13:32   0:00 grep fill_mem.exe
25 *************
26 allocation 5 ... n = 1250
27 1000     12350  0.0  0.0 15271572 956 pts/1    S+   13:32   0:00 ./fill_mem.exe
28 1000     12377  0.0  0.0   4400   612 pts/1    S+   13:32   0:00 sh -c ps aux | grep fill_mem.exe >> outfile
29 1000     12379  0.0  0.0   9384   916 pts/1    S+   13:32   0:00 grep fill_mem.exe
30 *************
31 allocation 6 ... n = 1260
32 1000     12350  0.0  0.0 15640720 956 pts/1    S+   13:32   0:00 ./fill_mem.exe
33 1000     12382  0.0  0.0   4400   616 pts/1    S+   13:32   0:00 sh -c ps aux | grep fill_mem.exe >> outfile
34 1000     12384  0.0  0.0   9384   920 pts/1    S+   13:32   0:00 grep fill_mem.exe
35 *************
36 allocation 7 ... n = 1270
37 1000     12350  0.0  0.0 16015776 956 pts/1    S+   13:32   0:00 ./fill_mem.exe
38 1000     12387  0.0  0.0   4400   616 pts/1    S+   13:32   0:00 sh -c ps aux | grep fill_mem.exe >> outfile
39 1000     12389  0.0  0.0   9384   920 pts/1    S+   13:32   0:00 grep fill_mem.exe
现在,我看到VSZ部分达到了~15GB,所以我假设当我试图解决更多问题时,它会失败

Operating system error: Cannot allocate memory
Allocation would exceed memory limit
因为没有那么多内存。然而,为什么RSS远低于这个数字呢?当我实际查看我的系统资源时,我看到大约140MB被用完了(我在Linux虚拟机中运行它,并通过Windows监控系统资源-我已经给了GM 16 GB的RAM供使用,因此我应该看到虚拟机内存不断增加,直到达到16 GB标记-值得一提的是,虚拟机具有VT-x/嵌套分页/PAE/NX,因此它应该像本机操作系统一样使用物理体系结构)

有人能解释一下为什么我的程序没有实际使用全部16 GB的RAM,以及我如何编写代码来保持我在RAM中创建的这些阵列—充分利用我可用的硬件


注意:我之所以尝试编写一个读取大量内存的示例程序,是因为我处理的数据在ascii文本中占用了大约14 GB的空间。在整个程序过程中,我需要大量处理数据,所以我希望一次读取所有数据,然后在整个程序运行期间从RAM中引用这些数据为确保正确执行此操作,我正在尝试编写一个简单的程序,该程序将同时在内存中存储一个非常大的数组(~15GB)。

您可能需要增加分配给堆栈的内存。例如,请参阅(注意:Fortran标准没有说明应该如何实现这一点,下面的描述是指Fortran编译器在当前操作系统上通常是如何实现的。)

当您执行ALLOCATE语句(或等效地,在C、FWIW中调用malloc())时,您实际上并没有保留物理内存,而是只为您的进程映射地址空间。这就是为什么VSZ上升,而不是RSS上升的原因。只有当您第一次访问内存时,才会为您的进程保留物理内存(通常为页面大小粒度,即大多数当前硬件上的4KB)。因此,只有当您开始将一些数据放入阵列时,RSS才会开始爬升

real_arr = 42.

应该把你的RSS增加到VSZ附近。

我把
real\u arr
数组改成一维,然后(分配后)给它分配随机值。我看到我在windows中的内存使用量猛增…但是现在Linux VB中的程序已经停止了-我没有看到windows中的RAM得到释放-有什么想法吗?!