Jump to content

návod Stack/heap size warning [****]


Tanga

Recommended Posts

Stack/heap size warning

 

Niektorým z vás sa už stalo, že pri kompilácii ste uvideli správu podobnú tejto:

Header size:             88 bytes
Code size:               60 bytes
Data size:                0 bytes
Stack/heap size:      16384 bytes; estimated max. usage=4064 cells (16256 bytes)
Total requirements:   16532 bytes

Je to chyba vášho kódu, ale kompiler ju nedokáže sám nájsť. Tým, čo nevedia o čo sa jedná, vysvetlím čo je to za chybu, ako ju nájsť a opraviť.

Text uvedený vyššie bol vygenerovaný pri kompilácii nasledujúceho kódu:

main() {
  new pole[4059];
}


Štruktúra AMX súboru

Keď sa skompilovaný .amx súbor nahrá do pamäte (pri spustení servera), má nasledovnú štruktúru:

+--------+
| prefix | <- metadáta o amx súbore, napr. adresy sekcií code a data, verzia kompilera, ..
| ------ |
|  code  | <- v tejto časti sa nachádza kód skriptu
| ------ |
|  data  | <- nemenné dáta, hlavne stringy
| ------ |
| stack  | <- časť pamäte, do ktorej sa ukladajú lokálne premenné
| ~~~~~~ | 
|  heap  | <- časť pamäte, do ktorej sa ukladajú globálne a static premenné
+--------+

Prefix má najnižšiu adresu v RAM a heap je na konci programu - najvyššia adresa v RAM.

Zásobník - stack

V stacku sú uložené všetky lokálne premenné. Pri spustení servera preto stack začína prázdny. Medzi heap a stack je v tom momente rezervovaný priestor. Podľa výstupu kompilera (uvedený vyššie) je defaultná veľkosť celej dynamickej oblasti 16KB.

Keďže veľkosť dát alokovaných na zásobníku sa nedá pri kompilácii predpovedať (lokálne premené vzniknú až počas behu programu), kompiler iba odhadne, že hrozí pretečenie zásobníka. Nedokáže povedať kedy ani kde. Avšak, ak už raz si myslí, že k nemu dôjde, tak mu treba veriť. V prípade, že nastane povestný stack overflow, tak dáta zo sekcie stack začnú prepisovať dáta zo sekcie heap (lokálne premenné zmenia chybne hodnoty globálnych premenných).

V Pawn každá premenná zaberá 4 bajty. Testovací kód vyššie, kde pole má 4059 prvkov, zaberie 16276 bajtov. Na stack sa tiež ukladajú ďalšie hodnoty, o ktorých programátor nemá prehľad, adresa návratu z funkcie, atď. Tieto dokopy budú mať tých 16 KB. Navyše, je to len odhad kompilera, že sa niečo stane.

new test0; /* zabera 4 bajty */
new test1[3]; /* zabera 12 bajtov */

Viac informácií nájdete na nete.

 

Ako to opraviť

Najrozumnejšie bude zoptimalizovať kód - odstrániť 256 bajtové polia, nepotrebné premenné a všetko bude fungovať. Sú gamemody rátajúc 100 000 riadkov, ktoré tento limit neprekračujú, prečo by mal váš skript prekračovať?

Pragma dynamic

V prípade, že už nemôžete optimalizovať viac, môžete manuálne zväčšiť dynamickú pamäť pre .amx súbor.

Direktíva preprocesoru pragma dynamic určuje koľko dynamickej (stack/heap) pamäte bude skript používať. Nastavíte to jednoducho pomocou

#pragma dynamic 17000 /* velkost dynamickej pamate v bajtoch */
Edited by Tanga
Úplné prepísanie, zjednodušenie
  • Líbí se mi to! (+1) 2
Link to comment
Share on other sites

Mne sa to stalo dnes, kvoli tomu napisal tento topic, ale mod mi isiel skompilovat aj spustit bez problemov, aj script ktory mi to robil fungoval ale ze vraj by to po case blblo tak som ten script odstranil...ja som sa na to este pozeral potom a planujem k tomu urobit rozsirenejsi navod, vvyborne sa cez to optimilizuje GM.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...