Come posso limitare la quantità di memoria disponibile per un processo?

10

Sto sviluppando un programma in corso; occasionalmente finisce per allocare una quantità molto grande di memoria (> > 10G su una macchina con 8G di memoria fisica), facendo sì che il sistema non risponda. Voglio limitare la quantità di memoria che il processo può allocare. Il solito modo in cui lo farei è:

ulimit -m 4000000 ; ./myprogram

... che dovrebbe uccidere il mio programma se tenta di utilizzare più di 4 GB di memoria.

Su OS X El Capitan questo sembra non avere alcun effetto; anche ulimit -m 1 (limitando tutti i programmi a solo 1kB di memoria!) è inefficace.

Come posso impostare un limite superiore sulla memoria disponibile per un particolare processo?

    
posta cpcallen 22.12.2016 - 15:56
fonte

1 risposta

1

Esistono due approcci per limitare l'utilizzo della memoria: ex post facto e preventivo. Vale a dire, puoi provare ad uccidere il tuo programma dopo che è diventato troppo grande, o puoi programmarlo per non diventare troppo grande in primo luogo.

Se insisti sull'approccio ex post facto, puoi utilizzare il seguente script Bash. Questo script prima trova la quantità di memoria (definita dalla "dimensione del set residente") che il processo con il pid processid sta usando, filtra tutti i dati non numerici usando grep e salva la quantità come variabile n. Lo script quindi controlla se n è maggiore della tua x specificata. Se lo è, il processo con pid processid viene ucciso.

Nota:

  1. Devi sostituire <pid> con l'id di processo del tuo programma.
  2. Devi sostituire <x> con rss="dimensione del set residente" (cioè la dimensione della memoria reale) che non vuoi che il programma superi.

n=$(ps -<pid> -o rss | grep '[0-9]') if [ $n -gt <x> ]; then kill -9 <pid>; fi

Se vuoi che questo venga eseguito ogni y secondi, basta inclinarlo in un ciclo e dirgli di attendere y secondi dopo ogni iterazione. Potresti anche scrivere un comando simile usando top . Il tuo punto di partenza sarebbe top -l 1|grep "<pid>"|awk '{print $10}' .

@ kenorb's answer mi ha aiutato con il mio script

Anche se credo che questo risponda alla domanda, a lungo termine credo che sia meglio progettare la programmazione per adottare un approccio preventivo utilizzando l'allocazione manuale della memoria.

In primo luogo, sei sicuro che l'utilizzo della memoria sia davvero un problema? La pagina Go documentation afferma:

The Go memory allocator reserves a large region of virtual memory as an arena for allocations. This virtual memory is local to the specific Go process; the reservation does not deprive other processes of memory.

Se pensi ancora di avere un problema, ti incoraggio a gestire manualmente la tua memoria come avviene nel linguaggio di programmazione C. Poiché go è scritto in C, sospettavo che ci sarebbero stati modi per entrare nella gestione / allocazione della memoria C, e in effetti ci sono. Vedi questo github repository che,

allows you to do manual memory management via the standard C allocator for your system. It is a thin wrapper on top of malloc, calloc and free from . See man malloc for details on these functions for your system. This library uses cgo.

Il caso d'uso è dato come:

Why would you want this?

When a program is causing memory pressure or the system is running out of memory it can be helpful to manually control memory allocations and deallocations. Go can help you control allocations but it is not possible to explicitly deallocate unneeded data.

Questa sembra una soluzione migliore a lungo termine.

Se vuoi saperne di più su C (compresa la gestione della memoria), La lingua di programmazione C è il riferimento standard.

    
risposta data 01.06.2017 - 18:41
fonte

Leggi altre domande sui tag