-
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?