Witam,
mam następujący problem, chodzi o to że uruchomiony program sukcesywnie zwiększa swój rozmiar w pamięci, przy dobowej pracy jego rozmiar jest średnio większy o jeden megabajt, sprawdziłem program pod względem wycieków pamięci i żadnych wycieków nie ma, do testów wykorzystałem chyba najlepszy do tego celu soft "EurekaLog". Co może być powodem tego problemu ?
...wycieki pamięci. zewnętrzne programy nie wyłapią wszystkich dziur w kodzie.
Jeśli chodzi o EurekaLog to nie jest to zewnętrzny program, on z tego co kojarzę jest dołączany podczas kompilacji... Dodam że kod sprawdziłem pod względem logicznym jeśli chodzi o obiekty dynamicznie tworzone i ich późniejsze zwalnianie, też specjalnie zrobiłem "wyciek pamięci" żeby zobaczyć jak zadziała EurekaLog i oczywiście zakomunikował mi o wycieku, jego wielkości i ile razy miało miejsce. Bardzo proszę o sugestię/informacje jak i gdzie szukać błędów.
bez co i jak robi program nikt Ci nic nie powie bo nie ma sensu zgadywać
Witam,
program nie jest skomplikowany ma w przybliżeniu 500 linii kodu, korzysta z TServerSocket, ADOConnection i ADOQuery, zasadza działania: podłączeni klient przesyłają dane z pomiarów które są zapisywane w bazie, to cała logika, dodam jeszcze że jest to napisane jako „servis systemowy”. Co do TServerSocket to dla każdego połączenia tworzy wątek.
a zakańczane są te wątki? a może gdzieś zostawiasz coś w stylu logów ?
Wszystkie wątki po rozłączeniu klienta są zakończone, do obsługi wąku dla klienta mam klasę dziedziczącą po TServerClientThread
"Najlepszy" chyba do łapania wycieków pamięci jest FastMM..
Po kolejnych testach jestem na 98% pewien że problem z przyrastającą zajętością pamięci jest po stronie ADO, prosty test jak zakomentowałem kod operujący na ADO problem jak ręką odjął.
Ale nadal nie wiem jak z tego problemu wybrnąć, proszę o dalsze rady;
Ps. jeszcze stestuje FastMM. Dziekuje za porade.
-------EDIT-------
Drążąc temat natknąłem się na http://delphi.about.com/od/kbthread/a/query_threading.htm
w przykładzie jest użyta funkcja CoInitialize(nil); oraz CoUninitialize(); z tego co tam napisane
The CoInitialize method initializes the COM library on the current thread. ADO is COM.
no więc jak tak ma być to tak zrobiłem, co prawda w konstruktorze mojego wątku dałem CoInitialize a w destruktorze CoUninitialize odpowiednio tworze/zwalniam obiekt ADOQuery. Ale do rzeczy ... nic to nie dało :-[ nawet powiem że więcej... zajętość programu w pamięci przyrastała szybciej [???]
Lecz to nie koniec mojej nierównej walki...
funkcje CoInitialize(nil); oraz CoUninitialize(); odpowiednio umieściłem w TService1.ServiceCreate i TService1.ServiceDestroy czyli pojedyncze ich wywołanie przy starcie serwisu i jego zamknięciu - wniosek, pamięć przyrasta dalej. Idąc tym samym tropem sprawdziłem też CoInitializeEx(nil,COINIT_MULTITHREADED); oczywiście bez pozytywnego skutku :-(
Proszę o poradę jak rozwiązać problem.
mozliwe ze masz cachowanie tej bazy danych. Jesli baza dziala ciagle to moze znaczyc ze zapytania sa przetrzymywane zeby dzialaly szybciej. Sprawdz to.
Witam i dziękuje za odpowiedź.
Coś w tym kierunku też kombinowałem, tzn obiekcie ADOConnection mam ustawiony kursor po stronie serwera bo myślałem że może to właśnie on coś "paskudzi" po testach wyszło że efekt ten sam :/ zresztą ja nie pobieram danych z serwera sql tylko je tam zapisuje wiec kursor też raczej nie ma z tym nic ...
Problem dalej pozostaje nierozwiązany.
podglądaj każdą zmienną (np. w TListBox poprzez TTimer)
sprawdź warunki pętli
Autre napisał(a)
podglądaj każdą zmienną (np. w TListBox poprzez TTimer)
sprawdź warunki pętli
I sprawdź czy na pewno piszesz program, a nie pamiętnik... :> Autre, poczytaj sobie o "podglądaniu": Debugowanie
Witam,
Autre napisał(a)
podglądaj każdą zmienną (np. w TListBox poprzez TTimer)
sprawdź warunki pętli
dziękuję za chęć pomocy, ale widać że nie czytałeś moich wypocin w tym temacie, napisałem wyraźnie że program jest pisany jako serwis działający pod systemem nie ma interfejsu graficznego a co za tym idzie raczej nie mam jak wyświetlić listbox-a, ale to szczegół.
Jeśli chodzi o "debugowanie" to poszło jako pierwsze i nie zaczynał bym tego wątku jak bym tego nie zrobił najpierw... tak samo wycieki logiczne w kodzie posprawdzane i takowych brak.
Jak już wcześniej pisałem prosty test jaki wykonałem to "zakomentowanie" kodu operującego na ADOQuery załatwia ten problem, no i funkcjonalność tego programu [green]
Jestem na 98% pewien że wina jest właśnie po stronie ADO a jeśli nie jego samego to opakowania go w VCL-a, taki szczegół nie wiem dlaczego nie ma metody ADOQuery.Unprepare; co prawda Prepare; jest ale nie widzę sensu jej używania bo jak podstawimy parametry to przy wywołaniu .Open;/.ExecSQL; to parametry są automatycznie wstawiane do zapytania... hmm to stare przyzwyczajenia z BDE.
naprowadzenie na "debugowanie" było przeznaczone tylko i wyłącznie dla Autre ;)