Witam wszystkich!
Pisze program w Dlephi 5.0, i jego kod źródłowy aktualnie ma ponad 6 tys. linijek. Znajduje się w nim kilka tablic, zmiennych (globalnych, globalnych), rekordów itp. Programik na moim kompie (procek to 1,6 GHz; 768 MBDDR RAM) uruchamia się bez problemu, natomiast w pracy przy procku 1,0GHz i chyba 64RAM, czasem się zawiesza. Czy w związku z tym jest może jakiś sposób na sprawdzenie jakie wymagania sprzętowe powinien mieć komp, aby wszystko działało poprawnie? Exe'k zajmuje ok. 600KB
Tylko nie piszcie, że pozostało mi tylko zoptymalizować kod :/
W API jest funkcja GlobalMemoryStatus, która zwraca strukturę MemoryStatus.
typedef struct _MEMORYSTATUS { // mst
DWORD dwLength; // sizeof(MEMORYSTATUS)
DWORD dwMemoryLoad; // percent of memory in use
DWORD dwTotalPhys; // bytes of physical memory
DWORD dwAvailPhys; // free physical memory bytes
DWORD dwTotalPageFile; // bytes of paging file
DWORD dwAvailPageFile; // free bytes of paging file
DWORD dwTotalVirtual; // user bytes of address space
DWORD dwAvailVirtual; // free user bytes
} MEMORYSTATUS, *LPMEMORYSTATUS;
Members
dwLength
Indicates the size of the structure. The calling process should set this member prior to calling GlobalMemoryStatus.
dwMemoryLoad
Specifies a number between 0 and 100 that gives a general idea of current memory utilization, in which 0 indicates no memory use and 100 indicates full memory use.
dwTotalPhys
Indicates the total number of bytes of physical memory.
dwAvailPhys
Indicates the number of bytes of physical memory available.
dwTotalPageFile
Indicates the total number of bytes that can be stored in the paging file. Note that this number does not represent the actual physical size of the paging file on disk.
dwAvailPageFile
Indicates the number of bytes available in the paging file.
dwTotalVirtual
Indicates the total number of bytes that can be described in the user mode portion of the virtual address space of the calling process.
dwAvailVirtual
Indicates the number of bytes of unreserved and uncommitted memory in the user mode portion of the virtual address space of the calling process.
W OnCreate pobierz pamięć, dzięki temu wiesz ile masz na starcie. Zapisz do pliku.
Dodaj jakiś przycisk na formę, pootwieraj wszystko co masz w programie i znowu pobierz pamięć. Zapisz do pliku. Nas interesuje pole dwAvailPhys czyli dostępna pamięć. Oblicz różnicę i wiesz ile bierze program. Podczas startu systemu wystarczy dodać warunek:
if MemoryStatus.dwAvailPhys < To_Co_Obliczyłeś then
begin
ShowMessage('Za mało pamięci');
Application.Terminate;
end;
Dziwi mnie trochę, że program się wiesza. Ja pisałem 10-tysięcznika, który wczytwuje około 70MB tablic. Wszystko realizuję na wskaźnikach. Tzn. jeżeli czegoś nie potrzebuję to zwalniam pamięć. Pomyśl nad dynamiczną deklaracją niektórych tablic. Powinno pomóc, a przeróbka programu będzie niewielka.
Później wystarczy dać New I Dispose i masz gotową optymalizację.
grizelda
Gdy zabraknie pamięci to program się nie zawiesza - w delphi wygląda to tak:
alokujesz i brak ramu to jest generowany wyjątek, dalej będzie komunikat i ostatecznie -> terminate.
Pewnie masz za dużo zmiennych globalnych - grube MB.
Niektórzy szczególnie uzdolnieni deklarują bezpośrednio takie malutkie globalne tablice:
var tabliczka : array[1..10000, 1..10000] of integer;
pewnie też masz z 5 sztuk takich i 8 trochę mniejszych. :-D
Obiekty powyżej kilkuset bytesów trzeba zawsze tworzyć dynamicznie.
...tak, tak, wiem, wiem - komputery mają teraz setki i tysiące MB, więc można szaleć...
Jeżeli chodzi o tablice to byłeś blisko :-), może nie mam tylu co podałeś, ale mam za to pięć takich tablic
var tabliczka : array[1..4, 1.. 5000] of integer;
</b>.
Dodam jeszcze fakt, że program zawiesza się w tym samym miejscu, co jakiś czas, i jak dobrze pamiętam (gdyż jesem w pracy, a programik w domu), to tam właśnie jest operacja na dwóch albo trzech tablicach. Jeżeli chodzi o kompa w pracy to jest to Win'2000 z prockiem 1GHz i 128MB RAMu.
Czyli najlepszym rozwiązaniem byłyby tablice dynamiczne?
Jakbys czytał uważnie mojego posta to byś wiedział
type
PTablica = ^TTablica;
TTablica = array [1..50000] of Integer;
var
Tablica :PTablica;
begin
New(Tablica); // tworzenie
x := Tablica^[indeks]; // odczyt
Tablica^[indeks] := x; // zapis
Dispose(Tablica); // zwalnianie pamięci
end;
Można też odwoływać się przez wskaźnikii, ale nie chcę mieszać.
PS. Masz tablicę integer. Przemyśl dobrze czy nie wystarczy np. Byte. Zaoszczędzisz 50% pamięci.
Czyli mam rozumieć że to by wyglądało w następujący sposób (zakładając żę po wciśnieciu buttona) :
procedure TForm1.pokaz_bazeClick(Sender: TObject);
begin
New(Tablica); // tworzenie
x := Tablica^[indeks]; // odczyt
// i w tym miejscu mają być instrukcje które zmieniają np. elementy tej tablicy??
Tablica^[indeks] := x; // zapis
Dispose(Tablica); // zwalnianie pamięci
end;
grizelda
Cawon napisał(a)
var tabliczka : array[1..4, 1.. 5000] of integer;
</b>.
Dodam jeszcze fakt, że program zawiesza się w tym samym miejscu, co jakiś czas, i jak dobrze pamiętam (gdyż jesem w pracy, a programik w domu), to tam właśnie jest operacja na dwóch albo trzech tablicach. Jeżeli chodzi o kompa w pracy to jest to Win'2000 z prockiem 1GHz i 128MB RAMu.
Czyli najlepszym rozwiązaniem byłyby tablice dynamiczne?
Jedna taka tablica zajmuje: 450004 = 80000 B
5 sztuk to poniżej 500KB = 0.5MB
Nie jest to wielkość, która pożre 30MB - a tyle powinno być dostępne, gdy jest 128MB w systemie.
Ile program zajmuje pamięci możesz sprawdzić w Menedżerze programów.
Masz inny błąd -> sprawdź algorytm - warunki w pętlach...
grizelda napisał(a)
Jedna taka tablica zajmuje: 450004 = 80000 B
5 sztuk to poniżej 500KB = 0.5MB
Nie jest to wielkość, która pożre 30MB - a tyle powinno być dostępne, gdy jest 128MB w systemie.Ile program zajmuje pamięci możesz sprawdzić w Menedżerze programów.
Masz inny błąd -> sprawdź algorytm - warunki w pętlach...
Jeżeli masz na myśli Menedzer zadań pod windowsem i tam sprawdzenie użycia pamięci do mojego programu, to ta wartość przy samym starcie wynosi 3500K, natomist w miejscu (w programie, gdzie się zawiesza komp w mojej pracyy) wynosi 3700K-3800K.
Inny błąd, algorytm, warunki, pętle? Hm... jeżeli byłyby one żle napisane, wówczas na moim domowym kompie też byłby taki problem (z wieszaniem się). A nie jest tak. Jednym słowem jest to dla mnie dziwne.
Spróbuje jeszcze z tym zwalnianiem pamięci, ale czekam na odpowiedz, podpowiedz mojego ostatniego postu :-)
Z góry dzięki