Garbage Collector

Hello,

I’m trying to learn haxe/openfl and my goal is to export to android. My cpp knowledge is basic.
The main thing that bugs me is the garbage collector and memory management. And the information is scarce to none-existent.

Does C++ haxe target have an implemented garbage collector ? If so, what are his limits/specifics (for example in flash events were a major GC problem for beginners) ? Can I manually free the memory?


Also, since I’m new to haxe how ok is to do this? :
@:access(openfl.events.EventDispatcher.foo)
public function removeAllEvents()
{
this.__eventMap = null;
this.__newEventMap = null;

}

Hi!

Yes, the Haxe C++ target does have a garbage collector. You can force a collection, you cannot forcibly delete a value (well, you could, but you will probably crash the application if you did). The references must be removed.

Flash has no “remove all listeners from a dispatcher” method… I suppose that the weak listener pattern is their solution to this. I had trouble with weak event listeners in Haxe C++ before (though now maybe it would be reliable enough to use?) though that still leaves HTML5 as leaking if you rely only on weak listeners.

The code you shared might do the trick on HTML5 – but the implementation is liable to change, and it won’t fix memory leak problems on Flash Player.

An “addObject”/“removeObject” pattern works well for adding and removing listeners, or you can use one container with listeners, and allow events to bubble

Is there a way to see if object has or hasn’t got references?


Something like this? Seems to work in flash and in c. Have to test it more though:

import openfl.display.MovieClip;
import openfl.events.EventDispatcher;

class GameObject extends MovieClip
{

	#if (flash || openfl_legacy)
	private var eventMap:Map<String,Array<EventListener>>;
	#end
	
	
	public function new() 
	{
	super();
	
	#if (flash || openfl_legacy)
	eventMap = new Map();
	#end
	
	}
    override public function addEventListener(type:String, listener:Dynamic->Void, useCapture:Bool = false, priority:Int = 0, useWeakReference:Bool = false):Void 
	{
		super.addEventListener(type, listener, useCapture, priority, useWeakReference);
		
		#if (flash || openfl_legacy)
		var listeners:Array<EventListener> = eventMap.get(type);
		if (listeners == null) 
		{
			listeners = new Array();
			eventMap.set(type, listeners);
		}
		if (parseLArray(listeners, listener) == -1) listeners.push(new EventListener(listener));
		
		#end
	}
	
	
	
	@:access(openfl.events.EventDispatcher)
	public function removeAllEvents()
	{
		#if (!flash && !openfl_legacy)
		
		this.__eventMap = null;
		this.__newEventMap = null;
		#else
		
		
		var k = eventMap.keys();
		var s:String;
		var a:Array<EventListener>;
		var l:Int;
		
		while (k.hasNext())
		{
			s = k.next();
			a = eventMap.get(s);
			l = a.length-1;

			while (0<=l)
			{
				removeEventListener(s, a[l].fun);
				l--;
			}
		}
		
		#end
	}
	
	override public function removeEventListener(type:String, listener:Dynamic->Void, capture:Bool = false):Void 
	{
		super.removeEventListener(type, listener, capture);
		
		#if (flash || openfl_legacy)
		var listeners:Array<EventListener> = eventMap.get(type);
		
		if (listeners != null)
		{
			var k = parseLArray(listeners, listener);
			if (k != -1) 
				listeners.splice(k, 1);
		
		}
		#end
	}
	
	
	private function parseLArray(a:Array<EventListener>, fun:Dynamic->Void):Int
	{
		var l:Int = a.length;
		for (i in 0...l)
		{
			if (a[i].equal(fun)) return i;
		}
		
		return -1;
	}
	
	
}

private class EventListener 
{
	
	
	public var fun:Dynamic->Void;
	
	public function new (_fun:Dynamic->Void) 
	{
		
		fun = _fun;
	}
	
	
	public function equal (_fun:Dynamic->Void):Bool
	{
		
		return Reflect.compareMethods (fun, _fun);
		
	}
	
	
}

No, unfortunately I’m not sure you can count the number of references to an object.

HxScout, hxcppObjectViewer and other tools can help show allocations, deallocations and other information about an application to check for leaks :slight_smile:

1 Like