-
31. Data: 2011-05-04 17:23:30
Temat: Re: typologia errorow aplikacji (a jeszcze leipaj i realoki)
Od: "Piotrek" <p...@p...onet.pl>
> W dniu 02.05.2011 20:37, f...@W...gazeta.pl pisze:
> > nie mozna, nie mozna miec leakow jak sie nie alokje ani dealokuje nawet
> > bita pamieci spoza statycznej puli
> Ależ można, można - starczy, że pobierzesz coś z puli a potem nie
> zwrócisz. W momencie gdy używasz puli jedyna różnica w porównaniu do
> malloc/free/realloc to to, że tracisz czas na pisanie samemu alokatora i
> ryzykujesz popełnienie w tym błędów.
Mógłbyś podać jakiś możliwie krótki przykład na występowanie wycieku w
programie bez dynamicznej alokacji? Jakoś nie mogę sobie tego wyobrazić (chyba
że używasz pojęcia wycieku w jakimś szerszym kontekście).
--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
-
32. Data: 2011-05-04 17:51:42
Temat: Re: typologia errorow aplikacji (a jeszcze leipaj i realoki)
Od: Michal Kleczek <k...@g...com>
Piotrek wrote:
>> W dniu 02.05.2011 20:37, f...@W...gazeta.pl pisze:
>
>> > nie mozna, nie mozna miec leakow jak sie nie alokje ani dealokuje nawet
>
>> > bita pamieci spoza statycznej puli
>
>> Ależ można, można - starczy, że pobierzesz coś z puli a potem nie
>
>> zwrócisz. W momencie gdy używasz puli jedyna różnica w porównaniu do
>
>> malloc/free/realloc to to, że tracisz czas na pisanie samemu alokatora i
>
>> ryzykujesz popełnienie w tym błędów.
>
> Mógłbyś podać jakiś możliwie krótki przykład na występowanie wycieku w
> programie bez dynamicznej alokacji? Jakoś nie mogę sobie tego wyobrazić
Np. jak uruchomisz JVM tak:
java -Xms512M -Xmx=512M ...
to nie ma dynamicznej alokacji pamieci (w sensie przydzialu pamieci przez
system operacyjny w trakcie dzialania programu - calosc jest alokowana na
starcie), a mimo to moze sie zdarzyc OutOfMemoryError bo w programie sa
"wycieki".
> (chyba że używasz pojęcia wycieku w jakimś szerszym kontekście).
Nie zapominaj, ze sterta (obslugiwana przez malloc/free) jest po prostu
jakas (dynamiczna) struktura danych, gdzie "danymi" sa bloki pamieci (pary
adresow). Nie ma znaczenia czy pamiec jest przez OS przydzielana w trakcie
dzialania programu (np. poprzez wywolanie sys_brk) czy tez na starcie jako
segment danych.
--
Michal
-
33. Data: 2011-05-04 18:29:45
Temat: Re: typologia errorow aplikacji (a jeszcze leipaj i realoki)
Od: "fir" <p...@p...onet.pl>
'out of memory error' to nie definicja wyciekow,
to dostajesz po prostu kiedy sie konczy pamiec
mz wycieki sa wtedy gdy ram zostal zaalokowany i nie zwolniony
a referencja do niego utracona
np tu nie ma wyciekow
for(int i =0 l i<1000000; i++) p[i] = malloc(1000000);
a sa tutaj
for(int i =0 l i<1000000; i++) p = malloc(1000000);
tamto mowienie o 'wyciekach' na statycznej tablicy mz
mozna porownac do sytuacji gdy nie zwalnia sie juz nie uzywanych
elementow stlowego wektora - to nie sa defakto wycieki tylko zapchanie
sobie kontenera
--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
-
34. Data: 2011-05-04 18:49:52
Temat: Re: typologia errorow aplikacji (a jeszcze leipaj i realoki)
Od: p...@p...onet.pl
> tamto mowienie o 'wyciekach' na statycznej tablicy mz
> mozna porownac do sytuacji gdy nie zwalnia sie juz nie uzywanych
> elementow stlowego wektora - to nie sa defakto wycieki tylko zapchanie
> sobie kontenera
te dwie rzeczy tj 'niepoodznaczanie rekordow w tablicy' i
'leaki w systemach z new' sa jakosciowo tak roznymi rzeczami
i roznia sie tak jak Francuz od Czeczena albo Gruszka od Marsa,
tak ze ten kto chce tu widziec to samo albo nawet podobne rzeczy
robi sobie sadlo z mozgu - nie chce mi sie wymieniac wszystkich
ych roznic ale chocby wspomiane ze druga z tych reczy to leaki
a pierwsza nie, albo np to ze w systemach z 'new' wyciec moze
wszystko, wyciec moze 127 albo ktoras z instancji 16 milionow
777 typow - gdy w c ze statycznymi tablicami nawet jak ktos zapchalby
tablice (a jest to naprawde wyjakowo GRUBY blad i zeby go ZROBIC
trzeba sie starac tak samo mocno jak o to by nie zrobic jakiegos
leaka bo o to jest dla odmiany nietrudno) to przy probie wstawienia
czegos do tej konkretnej tablicy z konkretnymi instancjami konkretnego
typu komunikat wypisze jawnie "brak miejsca w tablicy samolotow"
pozatym te instancje ktore nie sa wylaczone/odznaczone sa po prostu
uzywane i to widac
--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
-
35. Data: 2011-05-04 19:40:11
Temat: Re: typologia errorow aplikacji
Od: "fir" <p...@p...onet.pl>
> W dniu 2011-05-02 15:33, Michal Kleczek pisze:
> > fir wrote:
> >> na pewno mozna cos dorzucic, poszerzyc i pouszczegolawiac ta liste;
> >
> > Te powyzsze to najprostsze do naprawienia :)
> > Sa znacznie gorsze np
> > program zle policzy kapuste i firma pojdzie z torbami
> ...
>
> teraz wypowiedz na serio.
> W latach ... juz minionych, mialem i przeczytalem kilkakrotnie ksiazke
> (popularna seria z takim pascalowym zankiem podstawienia) o
> niezawodnosci autor (mniej wiecej) pisal sie Myers. Ksiazka (zupelnie
> poza tokiem studiow, z wlasnej inicjatywy kupiona) dla mnie formacyjna,
no ja z grubsza podzielilem sobie chwilowo bledy na dwie kategorie
uchwycane (( if(p==NULL) ...; assert(x>0) itp ))
i nie uchwycane,
nie uchwycane sa czasem zapewne przewaznie z lenistwa, bo niektore
mozna by powstawiawszy wiecej ifow pouchwycac, a czasem dlatego ze
trudno przewidziec i zauwazyc (w tym sensie byc moze mozna powiedziec
ze zawsze beda bledy nieuchwycane? - choc to toche teoria bo w praktyce
jest duzo bezblednych kodow)
- tego co zrobic z uchwycanymi mozna specjalnie nie rozwazac np by
nie poswiacac im za duzo wysilku wywalic od razu na sciane;
- porozwazac moze warto to co dzieje sie z nieuchwycanymi
--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
-
36. Data: 2011-05-04 20:00:43
Temat: Re: typologia errorow aplikacji (a jeszcze leipaj i realoki)
Od: Michoo <m...@v...pl>
W dniu 04.05.2011 20:29, fir pisze:
> tamto mowienie o 'wyciekach' na statycznej tablicy mz
> mozna porownac do sytuacji gdy nie zwalnia sie juz nie uzywanych
> elementow stlowego wektora - to nie sa defakto wycieki tylko zapchanie
> sobie kontenera
>
http://prowizorka.da.ru/~michoo/smieci/kod2.cpp
Czym się różni uruchomienie aplikacji skompilowanej z -DSTATIC_FIR i
bez? Tak czy tak pamięć wycieka - staje się niedostępna.
Co gorsza w przypadku "statycznym" istnieje spora szansa, że programista
po napotkaniu sytuacji końca bloku dojdzie do wniosku, że ustawił za
małe N i po prostu je powiększy. A w przypadku malloc/new valgrind
pięknie pokaże, że są błędy.
--
Pozdrawiam
Michoo
-
37. Data: 2011-05-04 22:02:24
Temat: Re: typologia errorow aplikacji (a jeszcze leipaj i realoki)
Od: p...@p...onet.pl
> W dniu 04.05.2011 20:29, fir pisze:
> > tamto mowienie o 'wyciekach' na statycznej tablicy mz
> > mozna porownac do sytuacji gdy nie zwalnia sie juz nie uzywanych
> > elementow stlowego wektora - to nie sa defakto wycieki tylko zapchanie
> > sobie kontenera
> >
> http://prowizorka.da.ru/~michoo/smieci/kod2.cpp
> Czym się różni uruchomienie aplikacji skompilowanej z -DSTATIC_FIR i
> bez? Tak czy tak pamięć wycieka - staje się niedostępna.
>
> Co gorsza w przypadku "statycznym" istnieje spora szansa, że programista
> po napotkaniu sytuacji końca bloku dojdzie do wniosku, że ustawił za
> małe N i po prostu je powiększy. A w przypadku malloc/new valgrind
> pięknie pokaże, że są błędy.
zauwazasz poprawne rzeczy tylko wypowiadasz odwrotne wnioski niz rozum
nakazuje - - jesli programista jest przekonany ze ma obecnie 'zywych' 30
samolotow, tablica jest na 100 i jest komunikat o zapelnieniu, to nie
zwiekszy limitu tylko sie zdziwi i zauwazy ze cos jest nie tak - a
z leakami tego moze nie zauwazyc; moze zauwazyc leaki albo nie, a jak
zauwazy leaki to niekoniecznie bedzie wiedzial ze to sa leaki z
samolotow i moze szukac tego przez dwa dni
inna rzecz jest tez taka co powtarzam, ze ja uzywam flagi .enabled
do odlaczania encji z petli przetwarzania - inaczej mowiac jesli ZAPOMNIALBYM
USUNAC obiektu ( free()/release()/dealloc() gzie indziej, a u mnie
samolot[i].enabled = false - jaki znikomy koszt!) to ten samolot nie
zniknie mi z petli przetwarzania i bedzie widzalny, poruszalny przez
algorytmy sztucznej inteligencji tak jak wszystkie inne wlaczone
obiekty - tu defakto nie ma potrzeby zwalniania po prostu jest tylko
potrzeba wylaczania - tak ze ten blad to nie blad zwlnienia a
blad wlaczenia obiektu - tak jakby ktos zapomnial wylaczyc postaci
jesli trafi ja kulka, w jezykach z alokacja tez trzeba cos wylaczyc
i dodatkowo usunac a tu tylko sie wylacza - tak ze blad wylaczenia
odpowiada tamtemu bledowi wylaczenia, a nie brakowi zwolnienia pamieci
tu sie troszczy tylko o wylaczanie (tak jak i tam) a kolejny krok
zwalniania pamieci juz nie istnieje i nie mozna o nim zapomniec
co do przykladu
#include <iostream>
const int ITER=3;
#ifdef STATIC_FIR
const int N=10;
int int_storage[N];
bool empty[N]={true};
int *get(){
for(int i=0;i<N;i++){
if(empty[N]){
empty[N]=false;
return int_storage+i;
}
}
return 0;
}
void put(int *ptr){
if(ptr >= int_storage && ptr <= (int_storage+N))
empty[ptr-int_storage]=true;
}
#define spawn get
#define release put
#else
#define spawn new int
#define release delete
#endif
int main(){
for(int i=0;i<ITER;i++){
int *a=spawn();
int *b=spawn();
//licz
release(b);
b=spawn();
a=spawn();
//licz
release(a);
release(b);
}
}
to mz nie jest adekwatny (pominawszy ze wolnego miejsca nie szukam w petli
od 0 do N tylko inkrementuje 'kursor' po kazdym wstawieniu na nastepne wolne
pole co srednio o ile pamietam sprowadza caly koszt do dwu i++ na wstawienie)
przyklad nie jest calkiem adekwatny bo ja nie symuluje mallokow/free
w alokatorach tu sie mysli bardziej 'rzeczowo' (troche jak przy zabawie
klockami)
addSamolot("spitfire", 10,20,30,15); //wstawiony
albo
samolot[i].enabled = false; //zdjety
i mozna uzyskac z petli np w kolizjach tak ze nawet o ile pamietam
przy tworzeniu nie trzeba ich nigdzie skladowac itp - nie mozna pochrzanic
relacji 1-1 miedzy wskaznikiem a blokiem ramu bo tu nie ma wskaznikow -
nie trzeba ich nigdzie trzymac - dafakto sa 'zabronione' tak, ze przyklad
jest niedobry
zreszta i tak pokazuje on roznice - po przejechaniu 100 razy tej petli
w wersji z alokami bedzie 100 osieroconych zgubionych w pozaprzestrzeni
nieusuwalnych blokow ramu z ktorymi nic nie mozna zrobic, a w wersji
statycznej po prostu tablica bedzie zapelniona stoma instancjami
i ten kod mozna nawet potraktowac jako funkcjonalny choc kaprysny
(bo tworzy sie trzysta z czego dwiescie sie usuwa) sposob
tworzenia stu instancji ktore pozniej moga spokojnie hulac
--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
-
38. Data: 2011-05-04 22:20:10
Temat: Re: typologia errorow aplikacji (a jeszcze leipaj i realoki)
Od: p...@p...onet.pl
> > Czym się różni uruchomienie aplikacji skompilowanej z -DSTATIC_FIR i
>
> > bez? Tak czy tak pamięć wycieka - staje się niedostępna.
staje sie niedostepna przez wskazniki ;-) tylko ze ja wskaznikow nie
uzywam ja operuje na calych 'setach'
// porusz wszystkie 'zywe'
for(int i=0; i<MAX; i++)
if(samolot[i].enabled) moveSamolot(i);
by jeszcze raz powiedziec - po odpaleniu swojego przykladu w petli 100
razy dostaniesz 100 niedostepnych blokow ramu skladajacych sie na wyciek,
a po odpaleniu tego w wersji z alokacj na tablicy 100 absolutnie poprawnie
zaalokowanych i dostepnych instancji gotowych do dzialania (i to warto
nadmienic z tego co kiedys mierzylem zaalokownych 20x-40x szybciej)
--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
-
39. Data: 2011-05-04 22:32:07
Temat: Re: typologia errorow aplikacji (a jeszcze leipaj i realoki)
Od: "fir" <p...@p...onet.pl>
> tworzenia stu instancji ktore pozniej moga spokojnie hulac
wogole to nie chcialem sie wdawac w takie dlugie wyjasnienia, chcialem
tylko owiedziec (a nawet wcale nie chcialem tego pwiedzec) tylko zauwazyc
ze tak jest:
w statycznym c NAPRAWDE nie ma takiego pojecia i problemu
jak leaki (jest to pojecie absolutnie nieznane)
jak ktos nie wierzy to mz jego problem
--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
-
40. Data: 2011-05-05 23:08:25
Temat: Re: typologia errorow aplikacji (a jeszcze leipaj i realoki)
Od: Andrzej Jarzabek <a...@g...com>
On 04/05/2011 18:23, Piotrek wrote:
>> W dniu 02.05.2011 20:37, f...@W...gazeta.pl pisze:
>
>>> nie mozna, nie mozna miec leakow jak sie nie alokje ani dealokuje nawet
>
>>> bita pamieci spoza statycznej puli
>
>> Ależ można, można - starczy, że pobierzesz coś z puli a potem nie
>
>> zwrócisz. W momencie gdy używasz puli jedyna różnica w porównaniu do
>
>> malloc/free/realloc to to, że tracisz czas na pisanie samemu alokatora i
>
>> ryzykujesz popełnienie w tym błędów.
>
> Mógłbyś podać jakiś możliwie krótki przykład na występowanie wycieku w
> programie bez dynamicznej alokacji? Jakoś nie mogę sobie tego wyobrazić (chyba
> że używasz pojęcia wycieku w jakimś szerszym kontekście).
Proszę bardzo, przykład życiowy i oczywisty: cache.
Mamy otóż zewnętrzny zasób, z którego dla jakiegoś klucza k możemy
otrzymać pewne dane, załóżmy mieszczące się w buforze stałej wielkości,
nazwijmy te dane rekordem. Ponieważ często żądamy tych samych rekordów,
piszemy cache trzymający ileś-tam wybranych rekordów w pamięci i
udostępniający wersję z pamięci zamiast odpytywać zasób.
Rekordy trzymane są w statycznej tablicy o zdefiniowanej stałą wielkości
N. Oprócz samych rekordów cache trzyma struktury pomcnicze; kontener
assocjacyjny (powiedzmy hash-table) pozwalający szybko sprawdzić czy
istnieje rekord dla daego klucza i jeśli tak, uzyskać namiary na niego,
oraz strukturę przechowującą wolne rekordy i pozwalającą pobrać
"następny wolny", załóżmy że to jest jakaś linked list. Obydwie te
struktury mogą być zrealizowane na statycznych tablicach.
Algorytm jest taki (dla uproszczenia jest to cache read-only działający
z założeniem, że rekodry trzymane zewnętrznie są niezmienne):
rekord pobierz(key k)
if (rekord r dla klucza k jest w hash table)
if (rekord r jest na liście wolnych elementów)
usuń r z listy wolnych elementów
inkrementuj licznik referencji na r
return r
else
if (lista wolnych elementów nie jest pusta)
pobierz i usuń pierwszy element r z listy wolnych elementów
pobierz dane dla klucza k z zewnętrznego zasobu
zamapuj k->r w hash table
return r
else
czekaj aż będą wolne elementy na liście
zwolnij (rekord r)
dekrementuj licznik referencji na r
if (licznik referencji wynosi 0)
wstaw r na koniec listy wolnych elementów
Przy pobieraniu rekordów usuwanie z listy i zliczanie referencji służy
oczywiście temu, żeby zbuforowany rekord, z którego klient akurat
korzysta, nie został w tym czasie nadpisany.
Co się w takim cache dzieje, jeśli kliencki algorytm pobiera rekordy z
cache, ale w niektórych sytuacjach "zapomina" zawołać procedurę
"zwolnij"? Otóż taki rekord pozostaje w cache po tym jak klient
przestanie z niego korzystać, kolejne próby czytania rekordu pod tym
samym kluczem odnoszą sukces (bo ten cachee pozwala wielu klientom na
raz czytać ten sam rekord), ale nigdy już nie trafia z powrotem na listę
wolnych elementów. W konsekwencji im dłużej cache będzie działał, tym
wolnych elementów na liście będzie mniej, a sam cache będzie coraz mniej
efektywny, aż w końcu wszyscy klienci próbujący pobrać kolejny rekord
zawisną czekając w nieskończoność na zaistnienie elementu na liście
wolnych, co nigdy nie nastąpi.
Jak nazwiesz taką sytuację, jeśli nie wyciekiem?


do góry
Dlaczego nowe mieszkania są coraz mniejsze? Dane GUS pokazują prawdziwy powód