Kontinuierlicher anstieg des Arbeitsspeichers

  • GM 8

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Kontinuierlicher anstieg des Arbeitsspeichers

    Hi zusammen, ich bin wieder mal auf ein Problem gestoßen.

    Seitdem ich mit Surfaces arbeite steigt der Arbeitsspeicher welchen mein Programm belegt Kontinuierlich in die höhe.

    Es ist leider erst sehr spät aufgefallen, also rekonstruieren ab wann das genau vorkommt... dazu brauche ich noch etwas.
    Ich dachte vielleicht weis jemand einen Tipp nach was ich suchen muss, oder was ich vergessen haben könnte.
    Ich habe eine alte Version meines Programms geladen bei der ich noch keine Surfaces benutzt habe und dort steigt die Belegung des Arbeitsspeicher nicht in die höhe.
    Ob es aber wirklich an den Surfaces liegt kann ich natürlich auf die schnelle nicht sagen.


    Eigentlich ist die Routine ganz einfach.

    Create:

    GML-Quellcode

    1. /// Erstelle das Surface
    2. sf_ABEF = surface_create(view_wview[0], view_hview[0]);
    3. surface_set_target(sf_ABEF);
    4. draw_clear_alpha(0,0);
    5. surface_reset_target();


    Draw:

    GML-Quellcode

    1. /// Zeichne etwas auf das Surface
    2. surface_set_target(sf_ABEF);
    3. draw_set_blend_mode_ext(var_blendMODEa[0], var_blendMODEb[0]);
    4. draw_sprite_ext(ds_map_find_value(Exist_Sprites, csi[2]), csi[3], csi[4], csi[5], 1, 1, 320, c_black, 1);
    5. draw_set_blend_mode(bm_normal);
    6. surface_reset_target();
    7. // Zeichne das Surface
    8. draw_set_blend_mode_ext(var_blendMODEa[1], var_blendMODEb[1]);
    9. draw_surface(sf_ABEF, 0, 0);
    10. draw_set_blend_mode(bm_normal);
    11. // Reinige das Surface
    12. surface_set_target(sf_ABEF);
    13. draw_clear_alpha(0,0);
    14. surface_reset_target();
    Alles anzeigen


    GameEnd:

    GML-Quellcode

    1. surface_free(sf_ABEF);


    Ich bin mir jetzt nicht Sicher ob es an den Surfaces liegt da ich noch nicht die Zeit hatte mich genauer damit zu beschäftigen (was ich aber noch tun werde).
    Aber vielleicht weis ja auf die schnelle sonnst jemand ob es daran liegen kann oder nicht (würde mir einiges an Zeit sparen).
    Für Hilfe wär ich sehr dankbar.

    mfg BoS

    EDIT: Hmm hab jetzt die alte Version gefunden und dort auf die schnelle provisorisch eingebaut das er auf ein Surface zeichnet bevor er es direkt Zeichnet, also so wie oben beschrieben, und der Arbeitsspeicher steigt auch nicht in die höhe, also liegt es wohl eher nicht an den Surfaces. Oder gibt es da etwas das Probleme machen kann wenn man mit mehreren Surfaces Arbeitet??

    EDIT: Also an der Anzahl der Instanzen kann es auch nicht liegen, die vermehren sich auch nicht, es sind nur 9 und da kommt auch nix hinzu.
    Jemand ne Idee woran es sonnst liegen könnte?
    Hmm.... vielleicht eine ds_map oder ds_liste in die ich immer mehr hinein packe und nicht lösche... aber 200KB / Sekunde ist doch etwas viel für ne ds_map.


    EDIT: Noch ein Nachtrag was ich vergessen habe zu sagen. Im Runner steigt der Arbeitsspeicherverbrauch NICHT an, nur wenn ich es Kompiliere und als EXE ausführe???

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von Balls of Steel ()

  • wie sieht es denn mit deiner Ressourcen Verwaltung aus? Benutzt du große Backgrounds/Sprite/Musik,....
    die möglicherweise Platz in deinem Arbeitsspeicher verbrauchen?

    Gerade großé Sounddateien sorgen da anscheindend oft für probleme,....



    Grüßle Blayde
  • Danke für deinen Tipp mit den Sounddatein, die zu überprüfen wär ich jetzt nicht drauf gekommen.

    Ich benutze auch relativ große Sounddatein, also ca 10 mp3's mit 2 Minuten dauer.
    Hab alle Sounddatein temporär entfernt, zum Glück lag es nicht daran :)

    Backgrounds benutze ich überhaupt nicht.

    Sprites eine menge, die größten sind etwa 600*600 Pixel.

    Mittlerweile konnte ich das Problem weiter eingrenzen.
    Ich habe mal die Übergabe der eingehenden Daten vom Server an die Engine für die Anzeige gestoppt, und der Speicher steigt nicht mehr an.
    Also muss das Problem irgendwo in der Verarbeitung der Daten liegen, die ich aufgrund der Surfaces umgestellt habe.

    Sobald ich weitere Hinweise gefunden habe melde ich mich wieder.


    EDIT: So, nach 5 Stunden suchen hab ich den Verursacher endlich gefunden :D

    Ich hatte in einem Script eine Switch Auswahl welche je nach Gebrauch verschiedene Variablen zurückgibt.
    Irgendwie verträgt sich return(); nicht mit der Switch Auswahl und lässt die Arbeitsspeicherbelegung langsam ins Unendliche ansteigen.
    Der wert wird richtig zurückgegeben weswegen es mir beim Programmieren auch gar nicht aufgefallen ist.

    GML-Quellcode

    1. switch(argument1)
    2. { case const_ART: return(var_OBJF); break;
    3. case const_SCHATTEN: return(var_ASSF); break;
    4. default : return(0);
    5. }


    Lösung: Bei Verwendung einer If Auswahl wird der Arbeitsspeicher nicht belastet.

    GML-Quellcode

    1. if(argument1 == const_ART)
    2. { return(var_OBJF);
    3. }
    4. else if(argument1 == const_SCHATTEN)
    5. { return(var_ASSF);
    6. }
    7. else
    8. { return(0);
    9. }


    Falls noch jemand eine Meinung dazu hat, oder gar weis warum das so ist, immer her damit, würde mich sehr interessieren. :)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Balls of Steel ()

  • Das ist ein sehr eigenartiges Problem 8|
    Bezüglich deines Codes:

    Balls of Steel schrieb:

    Ich hatte in einem Script eine Switch Auswahl welche je nach Gebrauch verschiedene Variablen zurückgibt.
    Irgendwie verträgt sich return(); nicht mit der Switch Auswahl und lässt die Arbeitsspeicherbelegung langsam ins Unendliche ansteigen.
    Der wert wird richtig zurückgegeben weswegen es mir beim Programmieren auch gar nicht aufgefallen ist.

    GML-Quellcode

    1. switch(argument1)
    2. { case const_ART: return(var_OBJF); break;
    3. case const_SCHATTEN: return(var_ASSF); break;
    4. default : return(0);
    5. }


    Da mit return das Script ohnehin beendet wird, benötigst du danach kein break.Vielleicht lässt der GM den Code irgendwo im Arbeitsspeicher herumliegen weil er darauf wartet zum break zu kommen und müllt ihn damit zu. Eine sehr vage Behauptung, da ich auch nicht 100% weiß wie der GM genau mit dem Code im RAM umgeht. Aber einen Versuch ist es Wert.

    © 2008 by Teamgrill Productions
  • Hm, ne, da hab ich andere Erfahrungen gemacht. In meinem aktuellen Projekt hab ich mehrere Skripte drin, die switch-Statements für ihre Rückgabewerte verwenden und von denen gut und gerne auch mal mehrere pro Step aufgerufen werden; eine nennenswerte RAMschändung ist da aber nicht zu erkennen. Ich benutz auch die eine oder andere Surface, die so ziemlich das ganze Spiel lang gelagert wird, aber die Dinger belegen generell auch nur den Platz, der ihnen am Anfang mal zugewiesen wird.
    Dafür hab ich das merkwürzige Phänomen erlebt, dass die Speicherauslastung permanent um ~200 kB gestiegen ist, als im Spiel mal mehrere 100 Objekte kurz nacheinander erstellt wurden, automatisch zum Spieler gezogen wurden, mit ihm kollidierten und dann das entsprechende Event im Spieler triggerten, inklusive instance_destroy() der angezogenen Objekte. Ich hab keinen Schimmer warum, aber als die Teile aus dem Spiel entfernt wurden, ging der reservierte Speicher für das Spiel um diese ominösen 200 kB hoch und blieb dann auf diesem neuen Wert.
    Verstehe das wer will, ich hab jedenfalls schon lang die Erkenntnis gewonnen, dass die Speicherverwaltung im GM ziemlich hart saugt. Absurde Bugs, die die RAM-Auslastung in turmhohe Turnhöhen treiben, klingen da ziemlich plausibel. Warum das aber ausgerechnet in diesem switch Statement hängen soll, ist mir ein ähnlich großes Mysterium wie euch. ^^
  • Irrenhaus3 schrieb:

    permanent um ~200 kB gestiegen ist

    Balls of Steel schrieb:

    200KB / Sekunde

    @Irrenhaus3
    Scheine da wenn auch auf andere weise auf den gleichen Bug gestoßen zu sein :D


    So wie ich das jetzt getestet habe (ca. 100 versuche) muss da eine ganz spezielle Kombination vorhanden sein :pinch:

    Netzwerk Event:

    GML-Quellcode

    1. /// Netzwerkfilter vom Login-Server und den Game-Servern
    2. var eventid_login = ds_map_find_value(async_load, "id");
    3. var buff_login = ds_map_find_value(async_load, "buffer");
    4. fcmd = buffer_read(buff_login, buffer_s16);
    5. //*** ANFANG DER CLIENT KOMMUNIKATION ZU DEN GAME-SERVERN
    6. if(fcmd == FCMD_GAME)
    7. { cmd = buffer_read(buff_login, buffer_s16);
    8. if(cmd == CMD_DEARS)
    9. { c = buffer_read(buff_login, buffer_s16); // von welchem Game-Server kommen die Daten
    10. c_dl = 0;
    11. c_dl = ds_list_find_value(obj_Client.all_connects, c); // Lies die ID der Verbindung aus falls vorhanden
    12. if(c_dl > 0) // Prüfe ob eine ID für die Verbindung existiert
    13. { if(c_dl.var_alive == true) // Prüfe ob die Verbindung aktiv ist
    14. { ds_list_clear(c_dl.all_sprites); // Leere alle verwendeten Listen vor der Wiederverwendung
    15. ds_list_clear(c_dl.all_sort);
    16. ds_list_clear(c_dl.all_sort_execute);
    17. c_dl.count = buffer_read(buff_login, buffer_s16); // wie viele Daten werden gesedet
    18. c_dl.clientx = buffer_read(buff_login,buffer_s16); // x
    19. c_dl.clienty = buffer_read(buff_login,buffer_s16); // y
    20. if(obj_DEBUG.var_debopt_net == true) // Debug-Modus Netzwerkübergabe an Engine sperren
    21. { var cmd = 0;
    22. var spr_name = "";
    23. var spr_ext = 0;
    24. c_dl.count_sprite = 0; // Anzahl der Sprites
    25. for(i = 0; i < c_dl.count; i++)
    26. { cmd = buffer_read(buff_login,buffer_s16); // Befehlart
    27. if(cmd == 0) // Bilddatei
    28. { c_dl.count_sprite++;
    29. ds_list_add(c_dl.all_sprites, buffer_read(buff_login,buffer_string) ); // Namensschild 1 0
    30. obj_Client.sort_id = buffer_read(buff_login,buffer_s32); // Instanz ID 2 1
    31. ds_list_add(c_dl.all_sprites, obj_Client.sort_id);
    32. spr_name = buffer_read(buff_login,buffer_string) // Sprite Name DRAW 3 2
    33. ds_list_add(c_dl.all_sprites, spr_name );
    34. ds_list_add(c_dl.all_sprites, buffer_read(buff_login,buffer_s16) ); // Sprite Animations Nr. DRAW 4 3
    35. ds_list_add(c_dl.all_sprites, buffer_read(buff_login,buffer_s32) ); // X-Position DRAW 5 4
    36. ds_list_add(c_dl.all_sprites, buffer_read(buff_login,buffer_s32) ); // Y-Position DRAW 6 5
    37. ds_list_add(c_dl.all_sprites, buffer_read(buff_login,buffer_s16) ); // X-Scale DRAW 7 6
    38. ds_list_add(c_dl.all_sprites, buffer_read(buff_login,buffer_s16) ); // Y-Scale DRAW 8 7
    39. ds_list_add(c_dl.all_sprites, buffer_read(buff_login,buffer_s16) ); // Winkel DRAW 9 8
    40. ds_list_add(c_dl.all_sprites, buffer_read(buff_login,buffer_s16) ); // Farbüberblendung DRAW 10 9
    41. ds_list_add(c_dl.all_sprites, buffer_read(buff_login,buffer_s16) ); // Sichtbarkeit DRAW 11 10
    42. obj_Client.sort_ebene = buffer_read(buff_login,buffer_f32); // Ebene 12 11
    43. ds_list_add(c_dl.all_sprites, obj_Client.sort_ebene);
    44. ds_list_add(c_dl.all_sort, obj_Client.sort_ebene); // SORTIERUNGSLISTE
    45. ds_list_add(c_dl.all_sprites, Auswahl_SUR(spr_name, "art")); // Sprite Filter Art SURFACE 13 12
    46. ds_list_add(c_dl.all_sprites, Auswahl_SUR(spr_name, "schatten")); // Sprite Filter Schatten SURFACE 14 13
    47. }
    48. var_hallo = script21("ob hier text steht oder leere klammern ist egal"); // ********** HIER DER AUFRUF DES SCRIPTS
    49. }
    50. ds_list_copy(c_dl.all_sort_execute, c_dl.all_sort);
    51. ds_list_sort(c_dl.all_sort_execute, false);
    52. }
    53. }
    54. }
    55. }
    56. else if(cmd == CMD_ADD_SERVER)
    57. {...
    Alles anzeigen


    script21

    GML-Quellcode

    1. { switch(argument0)
    2. { default: return(0);
    3. }
    4. }


    Es tritt nur das Speicherproblem auf wenn es in den beiden innersten klammern aufgerufen wird also in der for, oder in der if welche in der for ist.
    Ausserhalb macht es wieder keine Probleme.
    Zudem muss eine Variable vorhanden sein in welche es schreibt, und das Argument muss ein String sein.

    Naja ich lasse es hier jetzt mal gut sein, den noch genauer kann ich jetzt nicht mehr nachforschen, ich denke hoffe das es wirklich eine sehr spezielle Ausnahme ist und werde bei der weiteren Entwicklung auf alle fälle den Arbeitsspeicher im Auge behalten :D

    Wie lautet ein bekanntes Filmzitat? Es hat schon immer Geister in der Maschine gegeben... :thumbup:
  • Benutzer online 1

    1 Besucher