
I'm pulling my hair out fixing a memory leak in an OpenGL program.
Don't know if this is related to OpenGL, but I've not gotten any
takers from IRC. I know the exact line of code that's causing it.
I have a draw function as follows:
draw :: Int -> State -> IO ()
draw autoexit state = do
clear [ ColorBuffer, DepthBuffer ]
-- Configure camera and scaling
loadIdentity
setView state
-- Render Cells and iterate
c <- get $ cells state
forM_ c (renderCell state)
c' <- iter c
-- ==== MEMORY LEAK LIKE A SIEVE HERE ON THIS NEXT LINE
(cells state) $=! c'
swapBuffers
-------------
The state is defined as follows:
data State = State {
frames :: IORef Int,
t0 :: IORef Int,
eyex :: IORef GLdouble,
eyey :: IORef GLdouble,
eyez :: IORef GLdouble,
sphereList :: DisplayList,
cells :: IORef Population
}
And the iter function type is as follows:
iter :: Population -> IO Population
The only reason the IO is required is there is a random component and
I'm using the random number generator in the IO space. If I comment
out the one line mentioned above, there is no memory leak. The only
other references to the cells is in the initialization which creates
the first batch.
garbett:levy-gen garbetsp$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.10.1
cabal list output:
* OpenGL
Latest version available: 2.2.1.1
Latest version installed: 2.2.1.1
It looks like the old data that's in the IORef is never freed. Why
would this be occurring? Is there a compile flag that would fix this?
How can I force the garbage collection to free that memory?
My alternative is to use C/C++, and I really really don't want to do
that.
Shawn Garbett

On Jan 27, 2009, at 1:07 PM, Shawn Garbett wrote:
I'm pulling my hair out fixing a memory leak in an OpenGL program. Don't know if this is related to OpenGL, but I've not gotten any takers from IRC. I know the exact line of code that's causing it.
<snip> I've gotten it down to this: import Data.IORef import Graphics.Rendering.OpenGL.GL.StateVar -- THIS VERSION DOESN'T LEAK --iter :: IORef Integer -> IO () --iter ref = do -- i <- get ref -- ref $=! ((i+1) `rem` 12) -- iter ref -- --main = do -- ref <- newIORef (0::Integer) -- iter ref -- THIS VERSION DOESN'T LEAK --data State = State { stuff :: IORef Integer } -- --iter :: State -> IO () --iter state = do -- i <- get $ stuff state -- (stuff state) $=! ((i + 1) `rem` 12) -- iter state -- --main = do -- ref <- newIORef (0::Integer) -- iter State{stuff=ref} -- LEAKS LIKE A SIEVE data Leak = Leak {x :: Integer} data State = State { stuff :: IORef Leak } iter :: State -> IO () iter state = do l <- get $ stuff state (stuff state) $=! l{x=((x l) + 1 `rem` 12)} iter state main :: IO () main = do l <- newIORef $ Leak{x=0} let s = State{stuff = l} iter s
Shawn Garbett
at < vanderbilt.edu> Vanderbilt Cancer Biology 220 Pierce Ave, PRB 715AA Nashville, TN 37232 Office: 615.936.1975 Cell: 615.397.8737

Saizan on IRC offered the following solution: data Leak = Leak {x :: !Integer} Tested it and it works!
On Jan 27, 2009, at 1:07 PM, Shawn Garbett wrote:
I'm pulling my hair out fixing a memory leak in an OpenGL program. Don't know if this is related to OpenGL, but I've not gotten any takers from IRC. I know the exact line of code that's causing it.
<snip>
I've gotten it down to this:
import Data.IORef import Graphics.Rendering.OpenGL.GL.StateVar
-- LEAKS LIKE A SIEVE data Leak = Leak {x :: Integer} data State = State { stuff :: IORef Leak }
iter :: State -> IO () iter state = do l <- get $ stuff state (stuff state) $=! l{x=((x l) + 1 `rem` 12)} iter state
main :: IO () main = do l <- newIORef $ Leak{x=0} let s = State{stuff = l} iter s
Shawn Garbett
at < vanderbilt.edu> Vanderbilt Cancer Biology 220 Pierce Ave, PRB 715AA Nashville, TN 37232 Office: 615.936.1975 Cell: 615.397.8737
Shawn Garbett
participants (1)
-
Shawn Garbett