2016-05-03 3 views
1

Я попал в ловушку в проводной ситуации; мой код c++ продолжает потреблять больше памяти (около 70G), пока весь процесс не будет убит.Увеличение объема памяти

Я вызываю код C++ от Python, который реализует алгоритм Longest common subsequence length.

C++ код показан ниже:

#define MAX(a,b) (((a)>(b))?(a):(b)) 

#include <stdio.h> 

int LCSLength(long unsigned X[], long unsigned Y[], int m, int n) 
{ 

    int** L = new int*[m+1]; 
    for(int i = 0; i < m+1; ++i) 
    L[i] = new int[n+1]; 

    printf("i am hre\n"); 

    int i, j; 
    for(i=0; i<=m; i++) 
    { 
    printf("i am hre1\n"); 
    for(j=0; j<=n; j++) 
    { 
     if(i==0 || j==0) 
      L[i][j] = 0; 
     else if(X[i-1]==Y[j-1]) 
      L[i][j] = L[i-1][j-1]+1; 
     else 
      L[i][j] = MAX(L[i-1][j],L[i][j-1]); 
    } 
    } 
    int tt = L[m][n]; 

    printf("i am hre2\n"); 

    for (i = 0; i < m+1; i++) 
    delete [] L[i]; 

    delete [] L; 

    return tt; 
} 

И мой Python код выглядит так:

from ctypes import cdll 
import ctypes 
lib = cdll.LoadLibrary('./liblcs.so') 

la = 36840 
lb = 833841 
a = (ctypes.c_ulong * la)() 
b = (ctypes.c_ulong * lb)() 

for i in range(la): 
    a[i] = 1 
for i in range(lb): 
    b[i] = 1 

print "test" 
lib._Z9LCSLengthPmS_ii(a, b, la, lb) 

ИМХО, в C++ коде, после new операции, которая может выделять большое количество памяти в куче, не будет больше дополнительного потребления памяти внутри loop.

Однако, к моему удивлению, я заметил, что используемая память продолжает расти во время loop. (Я использую top на Linux, и он продолжает печатать i am her1, прежде чем процесс был убит)

Это действительно смутило меня в этот момент, как я предполагаю, что после выделения памяти, есть только некоторые арифметические операции внутри loop, почему код занимает больше памяти?

Я достаточно ясно? Может ли кто-нибудь помочь мне в этом вопросе? Спасибо!

+0

C и C++ разные языки! – Olaf

+6

'4 * (36840 + 1) * (833841 + 1) * 4 = 122878292488' Естественно потреблять более 70 ГБ памяти, если' int' занимает 4 байта. Он будет потреблять около 114 ГБ. – MikeCAT

+1

Я слышал, что 'malloc()' только резервная память и использование буфера фактически потребляет память. То же самое может случиться с «новым». – MikeCAT

ответ

1

Взгляните на то, что вы делаете:

#include <iostream> 

int main(){ 

    int m = 36840; 
    int n = 833841; 
    unsigned long total = 0; 

    total += (sizeof(int) * (m+1)); 

    for(int i = 0; i < m+1; ++i){ 
    total += (sizeof(int) * (n+1)); 
    } 

    std::cout << total << '\n'; 

} 

Вы просто потребляют слишком много памяти.
Если размер вашего int составляет 4 байта, вы назначаете 122 ГБ.

2

Потребление слишком много памяти. Причина, почему система не умирает от распределения происходит потому, что Linux позволяет выделить больше памяти, чем вы можете использовать

http://serverfault.com/questions/141988/avoid-linux-out-of-memory-application-teardown 

Я просто сделал то же самое на тестовой машине. Мне удалось преодолеть новые возможности и начать цикл, только когда система решила, что я ем слишком много доступной памяти, это убило меня.

Это то, что я получил. Прекрасное сообщение OOM в dmesg.

[287602.898843] Out of memory: Kill process 7476 (a.out) score 792 or sacrifice child 
[287602.899900] Killed process 7476 (a.out) total-vm:2885212kB, anon-rss:907032kB, file-rss:0kB, shmem-rss:0kB 

В Linux вы увидите что-то вроде этого в журналах ядра или в качестве выхода из dmesg ...

[287585.306678] Out of memory: Kill process 7469 (a.out) score 787 or sacrifice child 
[287585.307759] Killed process 7469 (a.out) total-vm:2885208kB, anon-rss:906912kB, file-rss:4kB, shmem-rss:0kB 
[287602.754624] a.out invoked oom-killer: gfp_mask=0x24201ca, order=0, oom_score_adj=0 
[287602.755843] a.out cpuset=/ mems_allowed=0 
[287602.756482] CPU: 0 PID: 7476 Comm: a.out Not tainted 4.5.0-x86_64-linode65 #2 
[287602.757592] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014 
[287602.759461] 0000000000000000 ffff88003d845780 ffffffff815abd27 0000000000000000 
[287602.760689] 0000000000000282 ffff88003a377c58 ffffffff811d0e82 ffff8800397f8270 
[287602.761915] 0000000000f7d192 000105902804d798 ffffffff81046a71 ffff88003d845780 
[287602.763192] Call Trace: 
[287602.763532] [<ffffffff815abd27>] ? dump_stack+0x63/0x84 
[287602.774614] [<ffffffff811d0e82>] ? dump_header+0x59/0x1ed 
[287602.775454] [<ffffffff81046a71>] ? kvm_clock_read+0x1b/0x1d 
[287602.776322] [<ffffffff8112b046>] ? ktime_get+0x49/0x91 
[287602.777127] [<ffffffff81156c83>] ? delayacct_end+0x3b/0x60 
[287602.777970] [<ffffffff81187c11>] ? oom_kill_process+0xc0/0x367 
[287602.778866] [<ffffffff811882c5>] ? out_of_memory+0x3bf/0x406 
[287602.779755] [<ffffffff8118c646>] ? __alloc_pages_nodemask+0x8fc/0xa6b 
[287602.780756] [<ffffffff811c095d>] ? alloc_pages_current+0xbc/0xe0 
[287602.781686] [<ffffffff81186c1d>] ? filemap_fault+0x2d3/0x48b 
[287602.782561] [<ffffffff8128adea>] ? ext4_filemap_fault+0x37/0x51 
[287602.783511] [<ffffffff811a9d56>] ? __do_fault+0x68/0xb1 
[287602.784310] [<ffffffff811adcaa>] ? handle_mm_fault+0x6a4/0xd1b 
[287602.785216] [<ffffffff810496cd>] ? __do_page_fault+0x33d/0x398 
[287602.786124] [<ffffffff819c6ab8>] ? async_page_fault+0x28/0x30