Проблем с паметта в ASP.NET (2.0)
18 отговора
0 прегледа
Проблем с паметта в ASP.NET (2.0)
Знам, че темата е за .net, но там е голяма боза ;)
И така, имам едно асп.нет приложение. Забелязах, че прогресивно трупа памет. Известно време профайлване показаха следните резултати:
1. Масата обекти са Gen2, т.е. няма да се разкарат лесно от паметта (въпреки това идея си нямам що се получава това).
2. Струва ми се, че се пазят предишни данни - напр. кликал съм по страница, кликал съм по друга страница, след това по трета, а една камара неща остават в паметта. Възможно ли е това да се определя от някоя настройка?
Масово в страниците ползвам байндване към дейтатейбъл - това дали е проблем? И ако да - какъв е стандартният подход за преодоляване?
Един интересен факт - направих си тестово приложение, което в общи линии се свежда до бутонче, лейбъл и клас със празен метод. най-общо казано, действието на бутончето се свежда до викане на GC.Collect(), изписване на свободната памет, викане на празния метод, GC.Collect() и изписване на свободната памет. За мое най голямо учудване като се клика бутончето, свободната памет намалява! на рекуест с по 9 КБ някъде. При това за почти празна страница, викаща метод, който не прави нищо.
Някой ако може да сподели идеи какво да пробвам за да се справя с проблема ще съм признателен :)
Мерси предварително.
Ние сме точици във вселената. А всеки човек е една цяла вселена...
И така, имам едно асп.нет приложение. Забелязах, че прогресивно трупа памет. Известно време профайлване показаха следните резултати:
1. Масата обекти са Gen2, т.е. няма да се разкарат лесно от паметта (въпреки това идея си нямам що се получава това).
2. Струва ми се, че се пазят предишни данни - напр. кликал съм по страница, кликал съм по друга страница, след това по трета, а една камара неща остават в паметта. Възможно ли е това да се определя от някоя настройка?
Масово в страниците ползвам байндване към дейтатейбъл - това дали е проблем? И ако да - какъв е стандартният подход за преодоляване?
Един интересен факт - направих си тестово приложение, което в общи линии се свежда до бутонче, лейбъл и клас със празен метод. най-общо казано, действието на бутончето се свежда до викане на GC.Collect(), изписване на свободната памет, викане на празния метод, GC.Collect() и изписване на свободната памет. За мое най голямо учудване като се клика бутончето, свободната памет намалява! на рекуест с по 9 КБ някъде. При това за почти празна страница, викаща метод, който не прави нищо.
Някой ако може да сподели идеи какво да пробвам за да се справя с проблема ще съм признателен :)
Мерси предварително.
Ние сме точици във вселената. А всеки човек е една цяла вселена...
Re: Проблем с паметта в ASP.NET (2.0)
може да се изпишат маса коментари на тази тема... накратко по:
1. какво те притеснява че масата обекти са Gen2? това не е критерии за почти нищо. GC ще си свърши работата когато намери за добре. Директното извикване на GC почти винаги до повече проблеми
2. да, но виж т.1 или казано накратко не му мисли
дойдохме и до важната част - датабайнинга. провери дали освобождаваш ресурсите след като свършиш работа с тях (т.е. дали викаш Dispose на каквито обекти изполваш - Dataset, DataTable и т.н.). това винаги има положителен ефект. използвай using(...) където можеш.
другото което може да направиш е да избереш по-лек контрол, примерно Repeater. трябва ли ти Viewstate? махни го където не е нужен.
относно "интересния" факт - виж т.1.
успех!
1. какво те притеснява че масата обекти са Gen2? това не е критерии за почти нищо. GC ще си свърши работата когато намери за добре. Директното извикване на GC почти винаги до повече проблеми
2. да, но виж т.1 или казано накратко не му мисли
дойдохме и до важната част - датабайнинга. провери дали освобождаваш ресурсите след като свършиш работа с тях (т.е. дали викаш Dispose на каквито обекти изполваш - Dataset, DataTable и т.н.). това винаги има положителен ефект. използвай using(...) където можеш.
другото което може да направиш е да избереш по-лек контрол, примерно Repeater. трябва ли ти Viewstate? махни го където не е нужен.
относно "интересния" факт - виж т.1.
успех!
Re: Проблем с паметта в ASP.NET (2.0)
В .NET всеки обект оцелял при преминаване на GC се премества в по-горен generation.
Виж дали викаш GC.Collect() някъде от кода и ако да - спри да го викаш, зашото при преминаването си, ако GC реши, че имаш достатъчно памет, ще се стартира и ще спре без да изтрие нищо, но автоматично всички обекти, непочистени от GC минават в по-горен generation.
Нормално е една камара неща да остават в паметта.
GC когато реши ще ги изтрие, но съвета ми е пак - ако не знаеш какво правиш по-добре не викай garbage collector-a.
И винаги използвай using() за IDisposable обекти, с които вече си си свършил работата.
Виж също каква е големината на DataTable-ите или DataSet-ите, имам впредвид, че не е добра идея например да изтеглиш 20 000 записа от базата, да напълниш един DataSet(или DataTable) и след това да го байнднеш към GridView което всъщност е на пейджове и показваш само 20 записа за страница.
Виж дали викаш GC.Collect() някъде от кода и ако да - спри да го викаш, зашото при преминаването си, ако GC реши, че имаш достатъчно памет, ще се стартира и ще спре без да изтрие нищо, но автоматично всички обекти, непочистени от GC минават в по-горен generation.
Нормално е една камара неща да остават в паметта.
GC когато реши ще ги изтрие, но съвета ми е пак - ако не знаеш какво правиш по-добре не викай garbage collector-a.
И винаги използвай using() за IDisposable обекти, с които вече си си свършил работата.
Виж също каква е големината на DataTable-ите или DataSet-ите, имам впредвид, че не е добра идея например да изтеглиш 20 000 записа от базата, да напълниш един DataSet(или DataTable) и след това да го байнднеш към GridView което всъщност е на пейджове и показваш само 20 записа за страница.
Re: Проблем с паметта в ASP.NET (2.0)
Остави GC-то на мира.
От профайлъра виж кои обекти остават в паметта и после иди и си оправи кода ... т.е. викай им .Dispose() или ползвай using .
Обмисли и смяна на професията
От профайлъра виж кои обекти остават в паметта и после иди и си оправи кода ... т.е. викай им .Dispose() или ползвай using .
Обмисли и смяна на професията
Re: Проблем с паметта в ASP.NET (2.0)
Извинявам се - мисля че беше редно да уточня няколко неща:
1. Аз също не съм привърженик на ръчното викане на GC. В тестовото приложение го направих с тестови цели.
2. DataTable обектите които ползвам се задават като DataSource на разни компоненти от потребителският интерфейс. Освен в деструктора (който се извиква на практика при всяка заявка, независимо postback или не, не ми идва на ум къде другаде мога да ги диспозна. В пристъп на параноя в базовия клас добавих деструктор (базовия клас на всичките ми страници е мой си клас, наследяващ Page), в който се обхождат всички контроли, ако имат дейтасорс, той се диспозва, чайлд контролите се диспозват и т.н. ефект - нулев.
3. За using съм наясно, както и за StringBuilder и за колекции, смятам, че проблема е по-различен.
4. Цялата тази акробатика се прави, защото на машина с примерно 750 мб памет, след като приложението позаеме едно солидно количество памет, започва да бави твърде много. По някое си време като съвсем свърши паметта част от нещата се забърсват и положението се подобрява, но преди това не ще. Това аз не съм го наблюдавал, за съжаление.
5. Смятам, че не би следвало по 800-900К памет да изчезва в небитието след ВСЕКИ рекуест.
Ако това може да е от някаква помощ - при по-тежките ни екрани (страници) отива повече памет, отколкото при по-леките
Ние сме точици във вселената. А всеки човек е една цяла вселена...
1. Аз също не съм привърженик на ръчното викане на GC. В тестовото приложение го направих с тестови цели.
2. DataTable обектите които ползвам се задават като DataSource на разни компоненти от потребителският интерфейс. Освен в деструктора (който се извиква на практика при всяка заявка, независимо postback или не, не ми идва на ум къде другаде мога да ги диспозна. В пристъп на параноя в базовия клас добавих деструктор (базовия клас на всичките ми страници е мой си клас, наследяващ Page), в който се обхождат всички контроли, ако имат дейтасорс, той се диспозва, чайлд контролите се диспозват и т.н. ефект - нулев.
3. За using съм наясно, както и за StringBuilder и за колекции, смятам, че проблема е по-различен.
4. Цялата тази акробатика се прави, защото на машина с примерно 750 мб памет, след като приложението позаеме едно солидно количество памет, започва да бави твърде много. По някое си време като съвсем свърши паметта част от нещата се забърсват и положението се подобрява, но преди това не ще. Това аз не съм го наблюдавал, за съжаление.
5. Смятам, че не би следвало по 800-900К памет да изчезва в небитието след ВСЕКИ рекуест.
Ако това може да е от някаква помощ - при по-тежките ни екрани (страници) отива повече памет, отколкото при по-леките
Ние сме точици във вселената. А всеки човек е една цяла вселена...
Re: Проблем с паметта в ASP.NET (2.0)
Ще ми простиш въпроса, но къде в такъв случай трябва да освободя тези ресурси, при условие че са дейтасорсове на контроли от графичния интерфейс. Имам предвид - в коя част на кода? в съседния пост, споменах, че опитах подобно нещо с деструктора на страницата.
Наясно съм, че може би идеята за използване на дейтатейбъл за дейтасорс на контрол може би не е блестяща, но в момента това е положението.
В този ред на мисли - според теб, за да сменя дейтасорса на контрол достатъчно ли е ctl.DataSource = x; ctl.DataBind(); или и там трябва да вземам дейтасорса, да го диспозна и тогава да сетвам новия дейтасорс - звучи ми странно, ама вече се чудя какви предположения да правя.
Ние сме точици във вселената. А всеки човек е една цяла вселена...
Наясно съм, че може би идеята за използване на дейтатейбъл за дейтасорс на контрол може би не е блестяща, но в момента това е положението.
В този ред на мисли - според теб, за да сменя дейтасорса на контрол достатъчно ли е ctl.DataSource = x; ctl.DataBind(); или и там трябва да вземам дейтасорса, да го диспозна и тогава да сетвам новия дейтасорс - звучи ми странно, ама вече се чудя какви предположения да правя.
Ние сме точици във вселената. А всеки човек е една цяла вселена...
Re: Проблем с паметта в ASP.NET (2.0)
ОК, оставяме GC на мира, и без това не съм се скъсал да го викам. Уточнявам пак, че в примерчето го викам за проба. При това не ми е много ясно как точно викането на GC.Collect ще качи паметта използвана то приложението. При това говоря за прогресивно качване на паметта, не еднократно (ако беше еднократно щях да го отдам на зареждането на кода за изпълнение в паметта).
Пак ще обясня, че от профайлъра видях примерно обекти, които са дейтасорсове на контроли в предишни страници. Как според теб трябва да ги диспозна? Пробвах в деструктора на страницата - нямаше особена файда, още повече, че те ако са във вюстейт няма кой знае какъв смисъл от диспозването щото обектите пак ще си дойдат от вюстейта (като се десериализират).
Относно последното - имаш ли оферта за метач, ама със заплата на програмист? Ослушвам се за такава ;)
Ние сме точици във вселената. А всеки човек е една цяла вселена...
Пак ще обясня, че от профайлъра видях примерно обекти, които са дейтасорсове на контроли в предишни страници. Как според теб трябва да ги диспозна? Пробвах в деструктора на страницата - нямаше особена файда, още повече, че те ако са във вюстейт няма кой знае какъв смисъл от диспозването щото обектите пак ще си дойдат от вюстейта (като се десериализират).
Относно последното - имаш ли оферта за метач, ама със заплата на програмист? Ослушвам се за такава ;)
Ние сме точици във вселената. А всеки човек е една цяла вселена...
Re: Проблем с паметта в ASP.NET (2.0)
Така де... всеки тред в тоя форум стига до темата за заплатата ;)
Re: Проблем с паметта в ASP.NET (2.0)
Еми при предложение за смяна на професията...
Ние сме точици във вселената. А всеки човек е една цяла вселена...
Ние сме точици във вселената. А всеки човек е една цяла вселена...
Re: Проблем с паметта в ASP.NET (2.0)
на въпроса в коя част в кода да се освободиш от ресурсите... така е ми е малко трудно да ти отговоря
ще се повторя - възможно най-скоро след като приключиш работа с ресурса. предложението ти да използваш деструктора не е досатъчно точно. става като котка която гони опашката си. GC не дава гаранция кога ще извика деструктора.
практически съвет - избери късно събитие на страницата (примерно Unload макар че имам някой съображения да е по-ранно събитие). друга добронамерена забележка относно "но в момента това е положението" - така не се прави. т.е. ако положението е оцапано не се страхувай да предприемеш по-крути мерки.
успех!
практически съвет - избери късно събитие на страницата (примерно Unload макар че имам някой съображения да е по-ранно събитие). друга добронамерена забележка относно "но в момента това е положението" - така не се прави. т.е. ако положението е оцапано не се страхувай да предприемеш по-крути мерки.
успех!
Re: Проблем с паметта в ASP.NET (2.0)
може да не съм бил абсолютно точен - бях сложил на страницата и метод Dispose в който ставаше цялата магария, а в деструктора само виках dispose.
Кога се вика Dispose нямам представа, но зачистването става след всеки рекуест. Резултата както описах - нулев.
Да разбирам, че примерно на Unload мога да закача код който ми диспозва всичките контроли и дейтасорсове? По-ранно събитие... кое ще да е то? В PreRender страницата още не и е време да се чисти - респонса още не е ренднат.
Под "Това е положението" имам предвид, че би касаело огромно количество работа, ако трябва да речем да разкарам всеки дейтатейбъл и да го заменя с рийдър и къстъм колекция. Приложението, в разработката на което участвам, е в много късен етап.
Поздрави и благодаря за отговора, дано има резултат!
Ние сме точици във вселената. А всеки човек е една цяла вселена...
Кога се вика Dispose нямам представа, но зачистването става след всеки рекуест. Резултата както описах - нулев.
Да разбирам, че примерно на Unload мога да закача код който ми диспозва всичките контроли и дейтасорсове? По-ранно събитие... кое ще да е то? В PreRender страницата още не и е време да се чисти - респонса още не е ренднат.
Под "Това е положението" имам предвид, че би касаело огромно количество работа, ако трябва да речем да разкарам всеки дейтатейбъл и да го заменя с рийдър и къстъм колекция. Приложението, в разработката на което участвам, е в много късен етап.
Поздрави и благодаря за отговора, дано има резултат!
Ние сме точици във вселената. А всеки човек е една цяла вселена...
Re: Проблем с паметта в ASP.NET (2.0)
Значи всичките тези момчета, дето ти говореха за гарбидж колектор, Диспосе, етц, етц в АСП.НЕТ - едно пръстче в дупето, кука - 20 метра у лево - и на боклука. Или в некоя Ц++ да пишат код за 500 лева.
Re: Проблем с паметта в ASP.NET (2.0)
Пирксе, остави философстването за теорията на събиране на боклука и почни от началото. Какво имаме:
1. На всеки рекуест се качва използваната памет. "Тече", както ще кажат по-старите кучета.
2. .НЕТ garbage collector-а е силно невероятно да има бъг, който да те ощетява :-)
Това значи, че имаш обект, който живее много дълго и държи референции към други обекти. Най-често съм виждал такива в следните случаи:
1. Някой тарикат прави сингълтън, който държи обект в статичен фийлд на някой клас и сингълтъна трупа и трупа обекти. Намери сингълтъна, махни го и застреляй автора му! (Имай предвид, че сингълтъна може да е зле маскиран като прост статичен фийлд или пропърти)
2. Някой простак трупа обекти в Session, Cache или Application обектите. Намери простака и му обясни да не го прави. Ако не слуша, процедирай като при автора на сингълтъна.
Как се диагностицира кои точно обекти седят в паметта? Малко трудно -- комбо с WinDbg и SOS.dll за твоя .НЕТ. SOS има команда !gcroot, която показва кои обекти държат референция към даден обект. За повече инфо виж този пост на Tess. Изобщо препоръчвам блога на Tess -- ще те направи по-добър .НЕТ програмист.
1. На всеки рекуест се качва използваната памет. "Тече", както ще кажат по-старите кучета.
2. .НЕТ garbage collector-а е силно невероятно да има бъг, който да те ощетява :-)
Това значи, че имаш обект, който живее много дълго и държи референции към други обекти. Най-често съм виждал такива в следните случаи:
1. Някой тарикат прави сингълтън, който държи обект в статичен фийлд на някой клас и сингълтъна трупа и трупа обекти. Намери сингълтъна, махни го и застреляй автора му! (Имай предвид, че сингълтъна може да е зле маскиран като прост статичен фийлд или пропърти)
2. Някой простак трупа обекти в Session, Cache или Application обектите. Намери простака и му обясни да не го прави. Ако не слуша, процедирай като при автора на сингълтъна.
Как се диагностицира кои точно обекти седят в паметта? Малко трудно -- комбо с WinDbg и SOS.dll за твоя .НЕТ. SOS има команда !gcroot, която показва кои обекти държат референция към даден обект. За повече инфо виж този пост на Tess. Изобщо препоръчвам блога на Tess -- ще те направи по-добър .НЕТ програмист.
Re: Проблем с паметта в ASP.NET (2.0)
Тъкмо мислех, как е добре човек да си поства с реалните имена тука и по едно време зех, че се отказах :) Ениуей, етъцъ и така нанататъка - Доброто си е отлично както признаваме по-простоватите хора.
Re: Проблем с паметта в ASP.NET (2.0)
Тесс освен че ги чатка дебъгерите, и бая става за пляскане. Поне 6-7 чикии съм си правил на снимката и.
Само си представи как те гледа нагоре, лееееко го полапва и ти казва колко лошо момче си, с какъв лош код.
Само си представи как те гледа нагоре, лееееко го полапва и ти казва колко лошо момче си, с какъв лош код.
Re: Проблем с паметта в ASP.NET (2.0)
О, Баче Кико, стига с тези факторита! О, баче кико, синглътън, не не, бачи Кико, не. Ти си лош програмист бачи кико.