0 Replies Latest reply on Mar 22, 2011 8:15 AM by edHPU

    Singleton 2d array and XML never gets cleared from memory

    edHPU Level 1

      Hey all,

      I have created a Network class singleton to represent our xml calls. The purpose of the class is to load in various xml calls and then load into a 2 dimensional array.The 2 main variables that I want to release are "mChannels" and "epgXML". When I call the function term(), the memory never gets released. I am initializing this Network class once (mNetwork = Network.init(), and then referencing the singleton through the getInstance function. I call the term() function but the memory never goes down. What am I doing wrong with garbage collection?

       

      import mx.utils.Delegate;
      import skitter.model.User;
      import skitter.model.Channel;
      import skitter.model.Host;
      import skitter.model.Program;
      import skitter.view.EpgGrid;
      import skitter.util.xmlLoader;
      import org.casalib.util.StringUtil;

      /****************************************
      * Network Object
      *
      * Singleton object that represents the live network
      * of channels and programs.
      *
      */
      class skitter.model.Network
      {
          private static var mBaseUrl:String = null;
          private static var mNetwork:Network = null;
          // keep count of the number of Singleton objects referenced
          private static var refCount:Number = 0;

         
          public static var isReady:Boolean = false;
          public static var isEpgReady:Boolean = false;
          public static var counter:Number = 0;
         
          private var epgXml:XML = null;
          private var epgExtraXML:XML = null;
          private var mChannels:Array = null;
          private var mCurrentChannelIndex:Number = 0;
          private var mUser:User = null;
          public var initialHourBlock:Number = 6; // initial hours to load into epg script
          public var extraHoursBlock:Number = 6;
          public var totalHoursLoaded:Number = 0; // counter for total number of hours loaded into mChannels array
          private var mEpgGrid:EpgGrid = null;
          private var mMessageInterval:Number = null;
          private var mStartupDelayInterval:Number = null;
         
          /**
           * Init the singletin Network class
           *
           */
          public static function init( )
          {
              trace( "Network.init(): mNetwork="+mNetwork );
              if( !mNetwork )
              {
                  mNetwork = new Network( );
                  counter ++;
              }
          }
         
          public static function term()
          {
              if( mNetwork )
              {
                  trace( "terminating network" );
                  isReady = false;
                  isReady = null;
                  delete isReady;
                 
                  isEpgReady = null;
                  delete isEpgReady;
                 
                  mBaseUrl = null;
                  delete mBaseUrl;
                 
                  mNetwork.epgXml = null;
                  delete mNetwork.epgXml;
                 
                  mNetwork.epgExtraXML = null;
                  delete mNetwork.epgExtraXML;
                 
                  //mNetwork.mChannels.length = 0;
                  var ii:Number = 0;
                  var jj:Number = 0;
                  var channel:Object;
                  var prog:Program;
                 
                 
                  trace("mNetwork.mChannels.length: " + mNetwork.mChannels.length);
                 
                  var mChannelsLength = mNetwork.mChannels.length;
                 
                  for (ii= mNetwork.mChannels.length-1; ii >= 0; ii -- )
                  {
                     
                      trace("channel: " + ii);
                      for (jj = 0;jj < mNetwork.mChannels[ii].mPrograms.length; jj++ )
                      {
                          trace("prog: " + jj);
                          prog = mNetwork.mChannels[ii].mPrograms.pop();
                          prog = null;
                          delete prog;
                      }
                 
                  channel = mNetwork.mChannels.pop();
                  channel = null;
                  delete channel;
                 
                  }
                 
                  mNetwork.mChannels.length = 0;
                  mNetwork.mChannels = null;
                  delete mNetwork.mChannels;
                 
                  mNetwork.mCurrentChannelIndex = 0;
                  mNetwork.mCurrentChannelIndex = null;
                  delete mNetwork.mCurrentChannelIndex;
                 
                  mNetwork.totalHoursLoaded = 0;
                  mNetwork.totalHoursLoaded = null;
                  delete mNetwork.totalHoursLoaded;
                 
                  mNetwork.initialHourBlock = null;
                  delete mNetwork.initialHourBlock;
                 
                  mNetwork.extraHoursBlock = null;
                  delete mNetwork.extraHoursBlock;
                 
                  EpgGrid.destroy();
                 
                  mNetwork = null;
                  delete mNetwork;
              }
          }
         
          /**
           * Get the network instance
           *
           */
          public static function getInstance():Network
          {
              refCount ++;

              return(mNetwork);
                  }
         
          /**
           * Constructor
           *
           */
          private function Network()
          {
              trace( "Creating new network instance" );
              mUser = User.getInstance();
             
              if( null == mUser.getSecondarySms() )
              {
                  isReady = true;
                  return;
              }
             
              mBaseUrl = mUser.getSecondarySms() + "/";

              clearInterval( mStartupDelayInterval );
              mStartupDelayInterval = setInterval( this, "loadEpg", Math.random( 2000) );
             
          }
         
          public function findChannelByNumber( chanNo:Number ):Channel
          {
              var ii:Number;
              var chan:Channel = undefined;
              var chanStr:String;
              var mChannelsStr:String;
             
              chanStr = StringUtil.trim( chanNo.toString() );
                     
              for( ii = 0; ii < mChannels.length; ++ii )
              {
                  mChannelsStr = StringUtil.trim( mChannels[ ii ].mNumber.toString() );
                  if( mChannelsStr == chanStr )
                  {
                      chan = mChannels[ ii ];
                      break;
                  }
              }
             
              return chan;
          }
         
          /**
           * Get the channel array
           *
           */
          public function getChannelArray( ):Array
          {
              return(mChannels);
          }
         
          /**
           * Get the current channel
           *
           */
          public function getCurrentChannel():Channel
          {
              return(mChannels[mCurrentChannelIndex]);
          }

          /**
          * Set the current channel based on the channel id.
          */
          public function setCurrentChannel( id:String )
          {
              var ii;
             
              trace( "setCurrentChannel( "+id+" )" );
              for( ii = 0; ii < mChannels.length; ++ii )
              {
                  //trace( "Comparing given id: "+id+" to ["+ii+"]="+mChannels[ii].mId );
                  if( mChannels[ ii ].mId.toString() == id.toString() )
                  {
                      mCurrentChannelIndex = ii;
                      trace( "Got a hit, mCurrentChannelIndex = "+ mCurrentChannelIndex );
                      break;
                  }
              }
          }
         
          /**
           * Get the next channel
           *
           */
          public function getNextChannel():Channel
          {
              if( mCurrentChannelIndex < mChannels.length-1)
              {
                  mCurrentChannelIndex++;
              }
              else
              {
                  mCurrentChannelIndex = 0;
              }
             
              return(mChannels[mCurrentChannelIndex]);
          }
         
          /**
           * Get the previous channel
           *
           */
          public function getPrevChannel():Channel
          {
              if( mCurrentChannelIndex > 0)
              {
                  mCurrentChannelIndex--;
              }
              else
              {
                  mCurrentChannelIndex = mChannels.length -1 ;
              }
             
              return(mChannels[mCurrentChannelIndex]);
          }
         
          /**
           * Load EPG data and create network hierarchy
           *
           */
          private function loadEpg( )
          {
              clearInterval( mStartupDelayInterval );
             
              var epgStr:String;
              var now:Date = new Date();
              var offset:Number = -(now.getTimezoneOffset() / 60);
             
              epgXml = new XML();
             
              mChannels = new Array();

              epgXml.ignoreWhite = true;
             
              isEpgReady = true;
             
              epgXml.onLoad = Delegate.create(this, onLoadXml);
             
              totalHoursLoaded += initialHourBlock;

              epgStr = new String( mBaseUrl + "/smsapi/getEpgData.php?sess="+User.getInstance().getSessionId()+"&hours="+initialHourBlo ck+"&tz=" + offset );
              epgXml.load(epgStr);
              trace( "Loading EPG data from: "+epgStr);
              return;
          }
         
          /**
           * onLoad function used to process XML
           *
           */
          private function onLoadXml(isLoaded:Boolean)
          {
              // Make sure we loaded
              if (!isLoaded)
              {
                  trace("Failed to load EPG XML file");
                  return;
              }

              if (epgXml.firstChild.nodeName == "channels")
              {
                  for (var ii:Number = 0; ii < epgXml.firstChild.childNodes.length; ii++)
                  {
                      var chan:Channel = Channel.createFromXml( epgXml.firstChild.childNodes[ii] );
                      mChannels.push(chan);
                     
                  }
              }
             
              trace("EPG XML Loading complete....");
              isReady = true;
             
              // gc
              epgXml = null;
             
              return;
          };

      }