казус на java (или подобни)

34 отговора 1587 прегледа
#1

казус на java (или подобни)

питам вече няколко приятели, дето имат опит с явата, ама получавам различни отговори. самия аз нямам опит, нито имам компилатор за да пробвам.
значи, какво ще се получи, ако създадем клас, в който има мембър от тип референс към нашия клас, и после създадем инстанция на която въпросния мембър насочим към самата нея. би трябвало да се получи теч на памет, понеже изглежда като че въпросния мембър някой го държи, но всъщност той е загубен за външния свят. от друга страна, ако за тая ситуация са се постарали да правят проверка, то все пак мога да вържа един милион инстанции на един милион класа по някакъв сложен начин, така че да се получи самопотдържаща се структура, в която всяка инстанция се държи от някоя друга, но графа който образуват е изолиран. струва ми се твърде невероятно мениджъра на паметта да обхожда графи и да търси изолираност - ако го направят така, дори най-простата операция по присвояване на указател, ще отнема огромно време за да се реши дали да се изтрие инстанцията която сочи или не.
та как явата и сродните и езици се справят с подобни ситуации?




NE SUTOR ULTRA CREPIDAM
Отговор
в отговор на zaphod #2

Re: казус на java (или подобни)

Добре, всеки мембър върви с указател към инстанцията му. Кво пречи при присвояване просто да се сравнява указателя с присвояваната стойност?



Отговор
в отговор на Pekoнcтpykтop #3

Re: казус на java (или подобни)

ами пречи това, че може да си ги вържеш на кръгче или още по-тежко на много много сложен граф. може да си направиш целия интернет като граф в паметта, после нулираш референса "вход към интернет" и цялото чудо увисва в паметта без някой да го държи.




NE SUTOR ULTRA CREPIDAM
Отговор
в отговор на zaphod #4

Re: казус на java (или подобни)

Кво ти пука?
Те тия дето им пука за мемърилийкс пишат на хасемблер.
като пишеш на жаба даваш високи систем реяуайърмънтс и си пишеш бозите.

Отговор
в отговор на zaphod #5

Re: казус на java (или подобни)

питам вече няколко приятели, дето имат опит с явата, ама получавам различни отговори.

Имат още много да учат тези твои приятели за Java-та.

струва ми се твърде невероятно мениджъра на паметта да обхожда графи и да търси изолираност - ако го направят така, дори най-простата операция по присвояване на указател, ще отнема огромно време за да се реши дали да се изтрие инстанцията която сочи или не.

Объркването ти изглежда идва от някои smart pointer-и в С++. Там наистина е нормално имплементациите на момента да правят калкулации.

За да бъде ясно, във всички версии на Java няма проблеми със събирането на паметта на циклични структури. Няма мемори лиик в Java.

Иначе има няколко алгоритъма и много настройки към тях за garbage collection в Java и човек може да си избере с кой и как да си пуска Java процеса. Понякога това оказва огромно влияние върху перфоманса на приложението.

Най-стария алгоритъм за справяне с цилкични референси е Mark-and-Sweep:
[линк]

Във википедиа обаче има по-добро обяснение как работи garbage collection-a в Java:
[линк]

Ето това е едно важно изречение от там:
"Generational garbage collection is a heuristic approach, and some unreachable objects may not be reclaimed on each cycle."

Отговор
в отговор на zaphod #6

Re: казус на java (или подобни)

Би имало проблем ако JVM-то работеше с reference counting вместо истински garbage collection.

Reference counting-a брои колко указателя сочат към даден обект и го деалокира като станат 0. има хубавото свойство да е предсказуем момента на унищожаване на обекта. Лошото са че не се справя с циклични графи и че е доста бавен (всяко присвояване на указател има overhead). Използва се най-вече в COM (и оттам VB).

Garbage collectors са доста различни алгоритми, които могат да бъдат оптимизирани за различни цели (например server i client JVM използват различни) и като цяло са по-бързи от reference counting. Почти всички езици с автоматично управление на паметта ползват GC, включително .NET. Основен недостатък е че програмите не могат да имат real-time requirements, защото изпълнението спира докато работи GC.

Отговор
в отговор на Nero #7

Re: казус на java (или подобни)

В интерес на истината в момента се правят опити да се докара джавата поне до soft real-time възможности - примерно разни екзотики като PERC, JBed(макар че това го спряха като продукт Esmertec преди доста време) или Jeode.
SUN от години имат дефинирана RTSJ спецификация, остава да видим дали някой ще избаца качествена имплементация, която да се наложи.

И да, GC алгоритмите са достатъчно умни, за да засекат циклични графи и един куп други гадости, които можеш да им измислиш. Не че не може да се получат течове на памет в Джава, но програмистът трябва доста да се "постарае" за да ги докара.

Отговор
в отговор на тepмит #8

Re: казус на java (или подобни)

На какъв принцип работят тези JVM със soft real-time възможности?

Ако не остава време, GC спира докъдето е стигнал и освобождава само част от паметта?

Отговор
в отговор на eфp. Лyk #9

Re: казус на java (или подобни)

боже, колко мъка има по този свят боже... нямало лийкове в ява - ти писла ли си на ява бре писателю? на ц++ е ясно, че не си... нещо взе да ми правиш впечатление (не че има някакво значение) с тъпотии в тъпи постове напоследък, дано не се налага да пишем заедно, макар че прекалено много станаха гъзлетата като теб и няма как да ви избегна...

Отговор
в отговор на Nero #10

Re: казус на java (или подобни)

прочетох линка на ефрейтора, където е описано как бачкат трасиращите боклукчии. не знам защо казваш че тия алгоритми са по-бързи от реф каунтърите, но дори да са по-бързи в средно време за изпълнение (иначе безспорно за промяна на една референция са по-бързи), то не ми харесва това че работата на програмата се накъсва.




NE SUTOR ULTRA CREPIDAM
Отговор
в отговор на zaphod #11

Re: казус на java (или подобни)

Като гледам описваш Сингълтона [линк].

А има една камара по-лесни начини да направиш мемори леак в Джавата. Просто ръгаш някави обекти във вектор, които имат една камара обекти закачени за тях. Виждал съм подобни случаи. Реален пример - апликейшън сървърите на Джава подддържат сесии. Там се държат някви бози в тези сесии. След изтичането на сесията контейнера си я праща за гарбиджване. Да ама некъв юнак (пишман прогрЪмист) ръга тези неща в някъв вектор, без да ги освобождава после. И всеки път като някой се включи в системата и се изключи паметта намалява.

Не случайно въведаха WeakHashMap [линк], където да можеш да ръгаш обекти, които могат да бъдат гарбаджнати ей тъй както си реши гарбидж колектора.

Както са казали колегите цикличните референции не са проблем за намиране отдавна.

Отговор
в отговор на gosling, james #12

Re: казус на java (или подобни)

Не си се обаждал досега рожбо, ха добре дошъл!

Хайде аз твърдя, че няма, ти твърдиш, че има; демонстрирай ми memory leak в Java. Какво трябва да направя? Пусни малко Java код най-добре.

Да не те хване шубето!

Поздрави,
Лук

П.С. Хубаво именце си си избрал. Напомняш ми за един дето се беше нарекъл гений, някой път ще разправя какви ги вършеше.

Отговор
в отговор на RealGuru #13

Re: казус на java (или подобни)

Да ама некъв юнак (пишман прогрЪмист) ръга тези неща в някъв вектор, без да ги освобождава после. това не е проблем на езика, формално погледнато, той запазва обектите така че това не е теч на памет, а претоварване на паметта.




NE SUTOR ULTRA CREPIDAM
Отговор
в отговор на RealGuru #14

Re: казус на java (или подобни)

А има една камара по-лесни начини да направиш мемори леак в Джавата.

Това което описваш не са memory leak в смисъла на memory leak, защото паметта продължава е достъпна. Java няма как да отгатне, че програмиста няма намерение да я използва повече.

Мемори проблемите, които описваш са съвсем реални проблеми, които имат свойството да се проявяват чак когато приложението отиде при клиента и затова са толкова интересни.

Можем да смятаме, че наличието на automatic garbage collection в един език за програмиране просто измества мемори проблемите на друга равнина.

Отговор
в отговор на eфp. Лyk #15

Re: казус на java (или подобни)

[линк] - малко е старо, но все пак ;) а ето и любимата ти ен-цикло-педия: [линк] - 'Languages that provide automatic memory management, like Java, C# or LISP, are not immune to memory leaks. Although the memory manager can recover memory that has become unreachable and therefore logically useless, it cannot free memory that is still reachable and therefore potentially still useful....'

Отговор
в отговор на genius #16

Re: казус на java (или подобни)

Накратко, понеже в Java може да се алокира памет докато даде OutOfMemory, значи в Java има memory leaks.

Ама ти наистина си бил genius!

Харесва ми новия ти ник.

Отговор
в отговор на eфp. Лyk #17

Re: казус на java (или подобни)

ми то е същото във всеки език - къде е разликата според теб? в ц също няма мемори лийк по твоята логика - в края на краищата можеш да 'свършиш' паметта от алокации, и щом не я освобождаваш, значи ти трябва? всички лийкове са логически - физически няма, то иначе рам-а щеше да е консуматив... ;)
може би си забелязал, че в статиите пише лийк все пак, а? и май не обичаш да признаваш грешки? ;)

не ми харесва ника ти стар - звучи ми шапкарски някак, но като се имат предвид изказванията които щедро ръсиш, може би все пак ти подхожда... :)

Отговор
в отговор на genius (mouse) #18

Re: казус на java (или подобни)

Ами не е съвсем така. По дефиниция мемори лийк е памет към която никой не сочи. Така че технически погледнато лийкове в в Java-та няма.
Сега ако обаче се замислиме защо толкова ни пречат тези лийкове ще установим че сами по себе си те нямат значение в голяма част от програмите. Типичен пример са програмите които се пускат еднократно. Например някой проверявал ли е ls командата има ли или няма мемори лийк? Или компилаторите. Там си е безсмисленна загуба на време е да се освобождава памет. Компилатора се стартира и като си свърши работата излиза и паметта се освобождава така или иначе. Та на кого му пука колко памет позлва, стига да може да компилира програмата пробелм няма.
Е да, но за други програми това дали паметта се освобождава е от значение. И точно там причината поради която паметта не е освободена е без значение. Например нещо си стои закачено на списък и никой не се е сетил да го изтрие от там, а дали е Java или C на кой му пука. Крайния резултат е един и същ. Програма излиза защото накрая остава без памет.
Така че тук си прав. Името е без значение. Обекта в контейнера е лийк както и да го кръстиш. Всъщност ако се замислим така наречените мемори лийкове не са толкова страшни. В края на краищата пуска се профайлер и се установява къде не е освободена коректно паметта. В логическите лийкове обаче познай дали точно този елелмент се ползва или не. Така че те са истинския проблем, а не мемори лийковете. А от това нито Java нито C са защитени.
А случайно да имате желание да коментираме фрагментацията на паметта? Ефрейторе само не казвай че такава няма.

Отговор
в отговор на genius (mouse) #19

Re: казус на java (или подобни)

Нещо не ти разбрах логиката. Струва ми се, че започна да дрънкаш глупости. Всъщност ти си по-известен с ник-а е "бай хуй" нали?

Отговор
в отговор на zzfe #20

Re: казус на java (или подобни)

А случайно да имате желание да коментираме фрагментацията на паметта? Ефрейторе само не казвай че такава няма.

С удоволствие бих коментирал фрагментацията или по-скоро липсата на такава.

Аз бих казал, че и има и няма фрагментация в Java. Има защото при алокациата и някои от режимите на работа на garbage colectora паметта се фрагментира и няма, защото при работата си garbage colectora е така добър и да дефрагментира паметта, защото това е Java. (.нет и той така)

Сега след като отвори въпрос гледам, че хората водят дискусии по този въпрос, но не намерих някой който да даде реален пример за проблем с фрагментацията в Java. Според някои обектите в perm space не били дефрагментирани, но дори и така да е това обикновено е най-малката част на картата на паметта.

Друг пък разправя, че с JNI можело да се локват части от паметта, така че дефрагментатора да не може да работи. Това май дори не е вярно, защото в JNI се ползва външна памет (или поне би трябвало).

Глeдам, че има и една интересна jvm-option
-XX:+UseCMSCompactAtFullCollection

Обаче е малко сложно обяснено какво точно прави. те май повечето advanced опции са оставени на потребителя сам да разбере как действат.

Между другото в последната версия на Sun Java вече има почти 500 jmv-options с които може да се стартира един Java процес. За всекиго по нещо един вид. А повечето Java програмисти никога не използват дори и една опция.

Отговор