<font face="verdana,sans-serif">Sounds hairy. Is there any way to get reference counting garbage collection in Haskell?<br></font><br><div class="gmail_quote">On Tue, Feb 7, 2012 at 9:26 AM, L Corbijn <span dir="ltr">&lt;<a href="mailto:aspergesoepje@gmail.com">aspergesoepje@gmail.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Tue, Feb 7, 2012 at 5:23 AM, Austin Seipp &lt;<a href="mailto:mad.one@gmail.com">mad.one@gmail.com</a>&gt; wrote:<br>


&gt; Just to clarify, this guarantee possibly could be made, ghc just doesn&#39;t do<br>
&gt; it now. In the past ghc never guaranteed a finalizer would ever be run.<br>
&gt;<br>
&gt; Regardless I would be wary of trusting finalizers to clean up very scarce<br>
&gt; resources. A malloc&#39;d buffer is probably fine to have a finalizer for,<br>
&gt; texture objects or file descriptors are a different matter. Predictability<br>
&gt; matters in those cases.<br>
&gt;<br>
&gt;<br>
&gt; Sent from my iPhone^H^H^H^H^HPortable Turing machine<br>
&gt;<br>
&gt; On Feb 6, 2012, at 10:16 PM, Austin Seipp &lt;<a href="mailto:mad.one@gmail.com">mad.one@gmail.com</a>&gt; wrote:<br>
&gt;<br>
&gt; It&#39;s a precise GC of course (conservative collection would be madness<br>
&gt; considering how much memory Haskell programs chew through.) That still<br>
&gt; doesn&#39;t ensure your finalizer will run during the next GC even if all the<br>
&gt; references are gone by then.<br>
&gt;<br>
&gt; Sent from my iPhone^H^H^H^H^HPortable Turing machine<br>
&gt;<br>
&gt; On Feb 6, 2012, at 10:09 PM, Clark Gaebel &lt;<a href="mailto:cgaebel@csclub.uwaterloo.ca">cgaebel@csclub.uwaterloo.ca</a>&gt;<br>
&gt; wrote:<br>
&gt;<br>
&gt; Is the Haskell garbage collector conservative, or precise?<br>
&gt;<br>
&gt; If it&#39;s conservative, then this will only usually work. If it&#39;s precise, it<br>
&gt; should always work.<br>
&gt;<br>
&gt; On Mon, Feb 6, 2012 at 10:56 PM, Ben Lippmeier &lt;<a href="mailto:benl@ouroborus.net">benl@ouroborus.net</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; On 07/02/2012, at 2:50 PM, Clark Gaebel wrote:<br>
&gt;&gt;<br>
&gt;&gt; &gt; I would be running the GC manually at key points to make sure it gets<br>
&gt;&gt; &gt; cleaned up. Mainly, before any scene changes when basically everything gets<br>
&gt;&gt; &gt; thrown out anyways.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; From the docs:<br>
&gt;&gt;<br>
&gt;&gt; newForeignPtr :: FinalizerPtr a -&gt; Ptr a -&gt; IO (ForeignPtr a)Source<br>
&gt;&gt; Turns a plain memory reference into a foreign pointer, and associates a<br>
&gt;&gt; finalizer with the reference. The finalizer will be executed after the last<br>
&gt;&gt; reference to the foreign object is dropped. There is no guarantee of<br>
&gt;&gt; promptness, however the finalizer will be executed before the program exits.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; &quot;No guarantee of promptness&quot;. Even if the GC knows your pointer is<br>
&gt;&gt; unreachable, it might choose not to call the finaliser. I think people have<br>
&gt;&gt; been bitten by this before.<br>
&gt;&gt;<br>
&gt;&gt; Ben.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; Haskell-Cafe mailing list<br>
&gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
&gt;<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; Haskell-Cafe mailing list<br>
&gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
&gt;<br>
<br>
</div></div>You have to be really careful with automatic cleanup using finalizers.<br>
Not only to the mentioned not cleaning up of resources but also to<br>
deleting it too early. What could happen is that you code doesn&#39;t<br>
explicitly use (= call a GL function with it) an object after binding<br>
it. Then it could be seen as a dead pointer and be deleted by it&#39;s<br>
finalizer. But thereby it might unbind the object from the binding<br>
point.<br>
Maybe a (more) realistic example is using only one shader program, you<br>
create it once, call usePorgram with it and never change it after<br>
that. As there is no other program to use you don&#39;t have to reactivate<br>
the program with useProgram or have to change anything about it. So in<br>
effect it&#39;s not used by Haskell anymore and the finalizer is run for<br>
it deleting the program. For a program this is not a big problem as<br>
the OpenGL spec tells you that it isn&#39;t deleted immediately so you can<br>
use it afterwards.<br>
<br>
With textures it&#39;s different, the are deleted immediately, so you may<br>
think you have a texture bound but in reality the finalizer might have<br>
run and deleted the texture for you. So watch doing the OpenGL memory<br>
management using the references in Haskell, as you might accidentally<br>
delete objects ahead of time.<br>
<br>
Lars,<br>
<br>
P.S. To make it worse, the bound objects (programs, textures, etc.)<br>
can also be queried and thereby there are non dead objects<br>
automatically, but there is no Haskell reference to them so the GC<br>
cannot now this.<br>
<div class="HOEnZb"><div class="h5"><br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
<br>
</div></div></blockquote></div><br>