przemal Napisano Wrzesień 30, 2008 Zgłoszenie Share Napisano Wrzesień 30, 2008 Witam, Może zacznę od pokazania fragmentu kodu a potem opiszę co i jak: //PLIK: UserInterface/UI/ui_TreeWidget.h ... class Ui_TreeWidget { public: QTreeWidget *treeWidgetList; ... } ... //PLIK: UserInterface/TreeWidget.h #include "UI/ui_TreeWidget.h" class TreeWidget : public QWidget, public Ui::TreeWidget { Q_OBJECT public: TreeWidget(QWidget* parent = 0); ~TreeWidget(); void update(QList<QTreeWidgetItem*> newList); }; //PLIK: UserInterface/TreeWidget.cpp #include "TreeWidget.h" void TreeWidget::update(QList<QTreeWidgetItem*> newList) { treeWidgetList->setUpdatesEnabled(false); treeWidgetList->setSortingEnabled(false); treeWidgetList->clear();//czyści listę ale nie zwalnia pamięci treeWidgetList->addTopLevelItems(newList); treeWidgetList->setSortingEnabled(true); treeWidgetList->setUpdatesEnabled(true); } //PLIK: UserInterface/MainWindow.h class MainWindow : public QMainWindow, public Ui::MainWindow { Q_OBJECT public: MainWindow(QWidget* parent = 0); ~MainWindow(); TreeWidget* treeWidget; }; //PLIK: Main/Application.h #include "../UserInterface/MainWindow.h" class Application : public QWidget { Q_OBJECT public: Application(); ~Application(); MainWindow mw; QList<QTreeWidgetItem*> list; void doSomething(); }; //PLIK: Application.cpp void Application::doSomething() { QTime time; time.start(); list.clear(); mw.treeWidget->treeWidgetList->clear();//wywołanie clear() tutaj czyści listę i zwalnia pamięć for(int i=0;i<10000;i++) { QTreeWidgetItem* item = new QTreeWidgetItem; item->setText(0, "some text"); item->setText(1, "some text"); item->setText(2, "some text"); item->setText(3, "some text"); list << item; } //mw.treeWidget->treeWidgetList->addTopLevelItems(list); mw.treeWidget->update(list); qDebug() << "ApplicationCore::doSomething() -> ??? in:" << time.elapsed() << "msec."; } I teraz tak, wywołanie metody clear() (metoda zdefioniowana w klasie QtreeWidget) wewnątrz klasy TreeWidget czyści listę ale nie zwalnia pamięci po tej liście, dopiero wywołanie clean() na obiekcie wyczyści listę i zwolni pamięć z tym że to też nie zawsze bo na początku program zajmuje około 9MB po stworzeniu pierwszej listy 19MB, po wyczyszczeniu przez obiekt i stworzeniu znowu listy (i tak kilka razy) (program zajmuje dalej 19MB zamiast tych 9 początkowych. Czy to ja coś źle tworzę, że czyszczenie listy z wnętrza klasy TreeWidget nie czyści pamięci po liście, czy jest to błąd w bibliotece QT ? Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
mikolajs Napisano Wrzesień 30, 2008 Zgłoszenie Share Napisano Wrzesień 30, 2008 Twój kod jest raczej niestandardowy. Spróbuj to napisać tak jak opisują w dokumentacji, może zadziała zgodnie z oczekiwaniem. W QT4 nie ma metody clean()! Trudno zrozumieć dokładnie o co pytasz. Być może chodzi Ci o to, że jeżeli tworzysz QList i dodajesz ją do QTreeWiget poprzez metodę QTreeWidget::addTopLevelItems ( const QList<QTreeWidgetItem *> & items ) to jak widać QList jest pobierane przez stałą referencję wiec po wywołaniu clear() na QTreeWidget nie może zwolić QList bo to musisz zrobić samodzielnie. Jeżeli chcesz zminiejszyć zużycie pamięci to skonstruuj program tak aby bezpośrednio dodawać QTreeWidgetItem do QTreeWidget, wtedy clear() zwolni pamięć. Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
przemal Napisano Październik 1, 2008 Autor Zgłoszenie Share Napisano Październik 1, 2008 dzięki za odpowiedz, tzn tak z tym clean to oczywiście literówka miało tam być clear() a nie dodaje bezpośrednio do QtreeWidget bo przez Qlist jest dużo szybciej. W kodzie oczywiście czyszczę także tą listę QList ale wyczyszczenie jej nie ma wpływu na pozycje w QtreeWidget które sobie dalej istnieją. Teraz trochę zmieniłem i lista QList jest czyszczona od razu po wrzuceniu elementów do QtreeWidget tak jest czytelniej. Nowa metoda doSomething(): //PLIK: Application.cpp void Application::doSomething() { QTime time; time.start(); //mw.treeWidget->treeWidgetList->clear(); for(int i=0;i<10000;i++) { QTreeWidgetItem* item = new QTreeWidgetItem; item->setText(0, "some text"); item->setText(1, "some text"); item->setText(2, "some text"); item->setText(3, "some text"); list << item; } mw.treeWidget->update(list); list.clear(); qDebug() << "ApplicationCore::doSomething():" << time.elapsed() << "msec."; } A teraz zamieszam jeszcze bardziej, bo wykonałem troszkę więcej tych cykli dodawania i usuwania przez tą moją metodę TreeWidget::update(QList<QTreeWidgetItem*> newList) z czyszczeniem listy QList i okazało się że pamięć jednak jest zwalniana tylko po 3 cyklach i po mimo wykonania 40 cykli dodawania, usuwania program zajmuje w pamięci coś około 29MB (zamiast tak jak przewidywałem ~410MB) - co mnie bardzo cieszy. A pytałem o to czemu czyszczenie listy (wywołanie treeWidgetList->clear()) z wnętrza klasy w pliku UserInterface/TreeWidget.cpp nie czyści pamięci (czyści tylko listę) a wyczyszczenie (wywołanie mw.treeWidget->treeWidgetList->clear()) listy dostając się do niej przez obiekt zwalnia pamięć. Teraz już wiem że pamięć jest jednak zwalniana tylko trochę później, więc w sumie problem rozwiązany. Jedyne co mnie jeszcze ciekawi to czemu po wyczyszczeniu obu list QList i QTreeWidget program w pamięci zajmuje 19MB zamiast 9 tak jak na początku, jeżeli ktoś wie czemu się tak dzieje i chciałby podzielić się tą informacją byłbym bardzo wdzięczny. Pozdrawiam, przemal Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
mikolajs Napisano Październik 1, 2008 Zgłoszenie Share Napisano Październik 1, 2008 Przecież zaraz po wyczyszczeniu listy (w metodzie update) tworzysz nową więc pamięć od razu jest wypełniana. Poza tym możliwe, że sama lista wewnątrz QTreeWigdetList jest implementowana za pomocą puli pamięci (rezerwowana jest ilość pamięci partiami, większa ilość niż w danej chwili się używa, aby po dodaniu nowego obiektu na liście nie od razu rezerowować nową pamięć, a dopiero po przekroczeniu dostępnej ilości pamięci rezerwuje się nową pulę [tak robi to np std::string]) Być może ta pula ma jakieś 20MB spróbuj stworzyć listy z inną ilością QTreeWidgetItem aby to sprawdzić. Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
Rekomendowane odpowiedzi
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto
Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.
Zarejestruj nowe konto
Załóż nowe konto. To bardzo proste!
Zarejestruj sięZaloguj się
Posiadasz już konto? Zaloguj się poniżej.
Zaloguj się