我有最小的代码,有两个问题,但现在只有一个问题。那个是我的内存泄漏几乎没有代码。另一个是过剩的迫使我使用unsafePerformIO只是为了让我可以拥有一个我可以在回调中使用的IORef(没有参数所以它需要是全局的)。是的,我复制了一些教程。
(不要担心间距):
{-# LANGUAGE ExistentialQuantification,
TemplateHaskell,
BangPatterns,
RecursiveDo,
GeneralizedNewtypeDeriving,
MagicHash #-}
module Game
( Game (..)
) where
import Entity
import Util
import GUtil
import Resources
import Control.Lens
import Control.Monad.State.Lazy
import Graphics.Rendering.OpenGL hiding (get)
import Graphics.UI.GLUT hiding (get)
import Data.IORef
import qualified System.IO.Unsafe --I'm so so sorry, it's to initialize some global references since the callbacks don't have parameters
data Game = Game
{ _root :: Entity
, _resources :: [Resource]
}
$(makeLenses ''Game)
gameRef :: IORef Game
gameRef = System.IO.Unsafe.unsafePerformIO (newIORef $ (Game (Entity ENull EDataNull []) []))
main :: IO ()
main = do
(progname, _) <- getArgsAndInitialize
createWindow "Hello World"
idleCallback $= doUpdateGame
displayCallback $= display
reshapeCallback $= Just reshape
mainLoop
reshape s@(Size w h) = do
viewport $= (Position 0 0, s)
postRedisplay Nothing
display :: IO ()
display = do
clear [ ColorBuffer ]
flush
doUpdateGame :: Maybe (IO ())
doUpdateGame = Just $ do
modifyIORef gameRef (snd . runState updateGame)
updateGame :: State Game ()
updateGame = do
return ()
在这一小部分代码中哪里有任何可能导致泄漏的问题?
答案 0 :(得分:1)
您不需要全局不安全的IORef
,只需使用部分应用程序。
粗糙且未经测试的代码:
idleCallback $= (doUpdateGame someLocalIORef)
...
doUpdateGame :: IORef Game -> Maybe (IO ())
doUpdateGame gameRef = Just $ modifyIORef gameRef (snd . runState updateGame)
此外,似乎没有任何东西强迫IORef
被评估,因此可能是空间泄漏。如果某些明显的严格注释没有帮助,请尝试进行分析。