Portál AbcLinuxu, 6. května 2025 20:40
convert
mi ho bez problémů zmenšil na 1500x1500, jen při tom potřeboval skoro 2 GB paměti (samozřejmě virtuální).
program požádá třeba o 1M ram a tu potřebuje dostat v celku, takže pro alokaci musí být v RAM volný blok o velikosti 1M.V Linuxe je to pravda, v BSD nikoli, tam neexistuje fragmentacia pamate.
program požádá třeba o 1M ram a tu potřebuje dostat v celku, takže pro alokaci musí být v RAM volný blok o velikosti 1M
Musí být volný blok virtuální paměti, ne fyzické (ta může být klidně celá plná - tedy až na rezervu definovanou v /proc/sys/vm/min_free_kbytes
).
To jste na omylu program požádá třeba o 1M ram a tu potřebuje dostat v celku, takže pro alokaci musí být v RAM volný blok o velikosti 1M.Nejsem expert na jadro ale jak to popisujete, tak mi z toho plyne, ze virtualni pamet je prakticky nanic. Resp. pokud by se neco odswapovalo, tak by to musel byt cely alokovany blok pameti. Funguje to opravdu takto? Ja zil doted v predstave, ze fyzicka pamet a pamet jak ji vidi proces spolu vubec nesouvisi a provadi se preklad v procesoru pomoci tabulek.
brk()
a mmap()
, natož user space - malloc()
, new
) samozřejmě pracuje s virtuální pamětí.
Aha, cili teda pulka bloku pameti zustane v RAM a druha bude na disku. Mezitim se ta odswapovana fyzicka RAM zaplni necim jinym (to je jedno cim) a nasledne nastane potreba priswapovat puvodni odswapovany blok zpet do RAM (rekneme, ze bude potreba). Protoze uz nemuze na sve puvodni misto, bude to nekam jinam. Dojde tedy k tomu, ze onen puvodni blok se ve fyzicke RAM "roztrhne". Proc tedy nejde naalokovat takto "roztrzeny" blok hned na zacatku, ale jak tvrdite, musi byt ve fyzicke RAM souvisly?
Nebo je nekde v me uvaze chyba?#include <stdlib.h> #include <stdio.h> #include <string.h> #define MAX 1024*1024 #define SIZE 1024*1024 char *pointers[MAX]; int main(void) { int i; char *tmp; char buf[16]; for (i = 0; i < MAX; i++) pointers[i] = NULL; for (i = 0; i < MAX; i++) { pointers[i] = malloc(SIZE); // memset(pointers[i], 'A', SIZE); if (pointers[i] == NULL) { fprintf(stderr, "Nemozem alokovat pamat (pointers)\n"); break; } } for (i = 0; i < MAX; i += 2) { if (pointers[i] != NULL) { free(pointers[i]); pointers[i] = NULL; } } tmp = malloc(SIZE*2); if (tmp == NULL) { fprintf(stderr, "Nemozem alokovat pamat (tmp1)\n"); } for (i = 0; i < MAX; i++) { if (pointers[i] != NULL) { free(pointers[i]); pointers[i] = NULL; } } tmp = malloc(SIZE*2); if (tmp == NULL) { fprintf(stderr, "Nemozem alokovat pamat (tmp2)\n"); } fgets(buf, sizeof(buf), stdin); return EXIT_SUCCESS; }
Ne, proč? User space aplikacím po fyzické paměti nic není, ty s ní vůbec nepřijdou do styku. To je to, co tu celou dobu od začátku tvrdím - že má-li convert
problémy s alokací paměti, není třeba přidávat fyzickou paměť, ale stačí dočasně zvětšit virtuální (přidáním swapu). Dokonce i ten zmiňovaný convert
si poradí s 32 MB fyzické paměti a 256 MB swapu…
malloc()
alokoval 224 MB blok (pochopitelně virtuální) paměti na počítači s 32 MB fyzické paměti a 256 MB swapem. Kdo nevěří, může si to klidně vyzkoušet sám.
ulimit -a
').
Na 256M to asi neuděláš. On je totiž rozdíl 250M v 256M fyzické a 650M v 256M fyzické.
Právě jsem zmíněnou operaci, tj. zmenšení 15000x15000 obrázku (644 MB TIFF) příkazem convert
z balíčku ImageMagick provedl na stroji s 64 MB fyzické paměti. Mám pro zajímavost zkusit ještě 32 MB?
tifftopnm -byrow big.tiff | pamscale -xscale=0.5 -yscale=0.5 | pnmtopng > output.pngTahle kolona zmenší původní tiff na polovinu a uloží výsledek ve formátu png
tifftopnm big.tiff >vystup.pnm pnmscale vystup.pnm -xscale=0.1 -yscale=0.1 > vystup_zmenseno.pnmToto cvičeni jsem provedl na P4 1.5GHz s 512 MB RAMM a šlo to docela rychle. Děkuji všem za odpovědi a názory na problém.
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.