• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Projector crashes "out of memory"

Community Beginner ,
Jun 13, 2022 Jun 13, 2022

Copy link to clipboard

Copied

We created a windows projector for our client. That .exe is running in a public exibition in the clients showroom. Unfortunately it crashes after a few hours running time with an "out of memory" error (says the log file provided by a technical partner). The app crashes even without user interaction and ram fills even when running during the night time.

 

The app is not very large and only has some information screens and a few buttons with event-listeners. No game, no 3D, etc...

 

Is there a problem with garbage collection while running? What causes the memory-usage?

Views

327

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 13, 2022 Jun 13, 2022

Copy link to clipboard

Copied

that's correct, there's a garbage collection issue (assuming the app's play-time is less than a few hours and it's the re-plays that are consuming more and more memory).

 

this is an excerpt from a book i wrote (Flash Game Development: In a Social, Mobile and 3D World):

 

To determine if you are practicing good memory management, you need to measure the memory used by your game. Fortunately, measuring system memory consumption is easy. ActionScript 3.0 has a static System class property totalMemory (or, totalMemoryNumber if you're using a lot of system memory), you can use to measure your game's memory consumption. Unfortunately, determining what is causing a memory problem, if you have one, is not so easy. I will address that in the next section.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jun 13, 2022 Jun 13, 2022

Copy link to clipboard

Copied

hey! thanks for your reply! unfortunately the book is not available in germany - so is there a best practice example in the web for good memory management in flash that you could recommend?

cheers!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 13, 2022 Jun 13, 2022

Copy link to clipboard

Copied

1/2 of the book was disappointing because of its layout so i don't know if i'd recommend buying it even if it were available.  the first 7 chapters were not impaired because of the layout so those are still very useful and it's in chapter 7 that app performance and memory management are discussed.  below is the most relevant information

 

 

 

Memory Tracking, Memory Use and Performance Testing

The code below is adapted from Damian Connolly's code at divillysausages.com.  The MT class reports frame rate, memory consumption and what objects are still in memory.  Using it is easy: Import it and initialize it from the document class

 

import com.kglad.MT;

MT.init(this,reportFrequency);

 

where this references your document class (i.e., the main timeline) and reportFrequency is an integer.  The main timeline reference is used to compute the realized frame rate and reportFrequency is the frequency in seconds that you want trace output reporting the frame rate and amount of memory consumed by your Flash game.  If you don't want any frame rate/memory reporting pass 0 (or anything less).  You can still use the memory tracker part of this class.

 

To track objects you create in your game, use:

 

MT.track(whatever_object,any_detail);

 

where the first parameter is the object you want to track (to see if it is ever removed from memory) and the second parameter is anything you want (typically a string that supplies details about what, where and/or when you started tracking that object).

 

When you want a report of whether your tracked objects still exist in memory, use:

MT.report();

 

I'll show sample code using MT after discussing details of the MT class in the MT class comments.  It is not necessary that you understand the class to use it but it is a good idea to check how the Dictionary class is used to store weak references to all the objects passed to MT.track()

 

Similar to the observer effect in physics, the mere fact that we are measuring the frame rate and/or memory and/or tracking memory, changes the frame rate and memory of the game.  However, the effect of measurement should be minimal if the trace output is relatively infrequent.  In addition, the absolute numbers are usually not important.  It is the change in frame rate and/or memory use over time that is important, and for that, this class works well.

 

This class does not allow more than once per second trace output to help minimize spuriously low frame rate reports caused by frequent use of trace.  (i.e., frequent trace output slows performance.) And, you can always eliminate trace output as a confounder of frame rate determination by using a textfield instead of trace output.

 

The MT class is the only tool needed to check memory usage and pinpoint memory problems, as well as, indirectly measure CPU/GPU usage (by checking actual frame rate of an executing app).

 

com.kglad.MT

package com.kglad{

       import flash.display.MovieClip;

       import flash.events.Event;

       import flash.utils.getTimer;

       import flash.system.System;

       import flash.utils.Dictionary;

       //  adapted from  @author Damian Connolly

       //  http://divillysausages.com/blog/tracking_memory_leaks_in_as3

       public class MT {

              // Used to calculate the real frame rate

              private static var startTime:int=getTimer();

              // Used to generate trace output intermittantly

              private static var traceN:int=0;

              // Megabyte constant to convert from bytes to megabytes.

              private static const MB:int=1024*1024;

              private static var mc:MovieClip;

              // d is used to store weak references to objects that you want to track.          // It is the essential object used to memory track in this class.                   // The true parameter used in the constructor designates that                        // all references are weak. That is, the dictionary reference itself                  // won't prohibit the object from being gc'd.

              private static var d:Dictionary = new Dictionary(true);

              // Used to trigger a report on the tracked objects

              private static var reportBool:Boolean;

              // Used to (help) ensure gc takes place

              private static var gcN:int;

              // This is the variable that will store the reportFrequency value that                   // you pass.

              private static var freq:int;

              // A constructor is not needed

              public function MT() {

              }

              // traceF() is the listener function for an Enter.ENTER_FRAME event.  If                 // the game is running at its maximum frame rate (=stage.frameRate),                 // traceF() will be called stage.frameRate times per second.

              private static function traceF(e:Event):void {

                     traceN++;

                     // This conditional ensures trace output occurs no more frequently                // than every freq seconds.  If the game is running at                               // stage.frameRate, output will occur at approximately freq                              // seconds.

                     if (traceN%(freq*mc.stage.frameRate)==0) {

                           // This is used to (try and) force gc.

                           gcN = 0;

                           forceGC();

                           trace("FPS:",int(traceN*1000/(getTimer()-startTime)),"||","Memory Use:",int(100*System.totalMemory/MB)/100," MB");

                           traceN=0;

                           startTime=getTimer();

                     }

              }

              // Called just prior to the above trace() and called just prior to a                     // memory report.  When called just prior to a memory report, reportBool                    // is assigned true.

              private static function forceGC():void {

                     // The first call to System.gc() marks items that are available                          // for gc.  The second should sweep them and the third is for good                // luck because you can't count on anything being predictably                        // gc'd when you think it should be.

                     mc.addEventListener(Event.ENTER_FRAME,gcF,false,0,true);

                     gcN = 0;

              }

              private static function gcF(e:Event):void {

                     // System.gc() initiates the gc process during testing only.  It                         // does not work outside the test environment.  So, if you are using this class to test a game that is installed on a mobile device, System.gc() will not clear memory of objects ready to be g

                     System.gc();

                     gcN++;

                     // 3 System.gc() statements is usually enough to clear memory of                         // objects that can be cleared from memory.

                     if (gcN>2) {

                           mc.removeEventListener(Event.ENTER_FRAME,gcF,false);

                           // Here's where reportBool being true triggers the memory                                // report.

                           if(reportBool){

                                  reportBool = false;

                                  reportF();

                           }

                     }

              }

              // Memory report.  All objects passed to d in the track() function,               // if they still exist, will be displayed by the trace statement along                // with the additional information you passed to track()

              private static function reportF():void{

                     trace("** MEMORY REPORT AT:",int(getTimer()/1000));

                     for(var obj:* in d){

                           trace(obj,"exists",d[obj]);

                     }

              }

              public static function init(_mc:MovieClip,_freq:int=0):void{

                     mc=_mc;

                     freq=_freq;

                     if(freq>0){

                           mc.addEventListener(Event.ENTER_FRAME,traceF,false,0,true);

                     }

              }            

              // This the function you use to pass objects you want tracked.

              public static function track(obj:*,detail:*=null):void{

                     d[obj] = detail;

              }

              // This is the function that triggers a memory report.

              public static function report():void{

                     reportBool = true;

                     forceGC();

              }

       }

}

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jun 13, 2022 Jun 13, 2022

Copy link to clipboard

Copied

It's impossible to answer your question without knowing exactly what your program is doing. It sounds like you have a memory leak, which means your code is continuously creating new objects, but never deleting them.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jun 14, 2022 Jun 14, 2022

Copy link to clipboard

Copied

Hi there!
The application is pretty simple - just a few clips on a main-timeline with some multiple choice questions and some sound and video players. I create sound- and video-objects which are deleted after play. The rest is event-listeners for buttons.
It runs as a windows-projector. The Win-Taskmanager shows a high memory-usage - but on a fast pc the usage drops faster than i am able to create an error - which means, there is a bit of a garbage collection working. 
 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 14, 2022 Jun 14, 2022

Copy link to clipboard

Copied

LATEST

it doesn't matter how "simple" it appears to you.  the issue for you is that your application is playing repeatedly.  each time your app ends you're leaving more "stuff" in memory that never gets cleared.

 

you need to either use object pooling or learn how to ready objects for gc.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines