[Haskell-cafe] Trashing of memory: How to troubleshoot and fix?
Joel Reymont
joelr1 at gmail.com
Sat Nov 5 05:10:02 EST 2005
Folks,
This is a I came up with a "scripting" environment for poker server
people to excercise their server. All it basically does is compose
and parse binary packets and let scripters send and receive them.
The issue I have is that the "script" runs fine on Mac OSX (1Gb of
memory, though 6Gb VM) and runs out of memory on a Windows machine
with 512Mb of memory and 768Mb of VM. The memory error is from malloc
which leads me to believe memory fragmentation could be an issue.
Running on Windows is a customer requirement.
I'm sending and receiving deeply nested structures although that is
not my call as the server is in C++. Most of the time just one or two
fields will be needed after the command is unpickled. Most of the
commands are converted to strings and written to a Chan for logging,
though.
I'm trying to launch 1000 scripts (separate threads) which just
connect to the server, login and disconnect. The big issue is that
the production scripts will run for hours, playing against one
another. If I the maximum that I can handle is about 200 scripts that
do nothing that I failed the project.
I was wondering if peak memory usage was the issue but jugding from
the GC stats it does not seem to be that high. Maybe I'm wrong. What
do you guys make of this?
./logon +RTS -p -sblah
GC summary:
--
5,695,379,620 bytes allocated in the heap
1,274,038,800 bytes copied during GC
69,790,544 bytes maximum residency (53 sample(s))
20433 collections in generation 0 (230.29s)
53 collections in generation 1 ( 5.15s)
152 Mb total memory in use
INIT time 0.00s ( 0.04s elapsed)
MUT time 91.13s (250.79s elapsed)
GC time 235.44s (607.31s elapsed)
RP time 0.00s ( 0.00s elapsed)
PROF time 0.00s ( 0.00s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 326.57s (858.14s elapsed)
%GC time 72.1% (70.8% elapsed)
Alloc rate 62,497,307 bytes per MUT second
Productivity 27.9% of total user, 10.6% of total elapsed
---
Time allocation and profiling report:
----
total time = 85.58 secs (4279 ticks @ 20 ms)
total alloc = 2,941,143,704 bytes (excludes profiling
overheads)
COST CENTRE MODULE %time %alloc
exp/evalU/cmd Script.Engine 50.0 66.4
connect Main 14.1 11.1
CAF Script.Engine 10.3 5.4
exp/if Script.Engine 8.8 4.8
send Main 6.4 6.7
expect Main 5.8 2.7
exp/evalU/sz Script.Engine 1.4 1.4
startSSL Script.Engine 1.3 0.1
---
expect -- receives command and unpickles it from a FastPackedString.
send -- pickles the command into a FastPackedString.
hGet from FPS:
---
hGet :: Handle -> Int -> IO FastString
hGet _ 0 = return empty
hGet h i = do fp <- mallocForeignPtr i
l <- withForeignPtr fp $ \p-> hGetBuf h p i
return $ PS fp 0 l
--
The code for send:
---
send :: Command -> EngineState ()
send cmd@(Command kind props) =
do liftIO $ yield
w <- get
let (_, cmd') = checkEncryption cmd
send_ cmd'
trace $ "Sent: " ++ show (kindOf cmd')
tracecmd cmd'
---
The code for expect:
---
expect :: [CmdType] -> EngineState ()
expect kind =
do w <- get
let h = socket w
secs = timeout_seconds w
(Right fps) <- liftIO $ timeout secs $ P.hGet h 4
trace $ "Size: " ++ show (P.unpackWords fps)
state <- liftIO $ hIsEOF h
trace $ "Connection closed: " ++ show state
(Right size', _) <- {-# SCC "exp/evalU/sz" #-}return $ evalU
fps appU
let size = fromIntegral $ (unLE size' :: Word16) - 4
(Right packet) <- liftIO $ timeout secs $ P.hGet h size
guard $ size == P.length packet
cmd' <- {-# SCC "exp/evalU/cmd" #-}return $ evalU packet appU
-- unpickle command
case cmd' of
(Left s, _) -> do trace $ "Error: " ++ s
throwError $ "Cannot parse: "
++ show
(P.unpackWords packet)
(Right _, _) -> do return ()
let (Right cmd'', _) = cmd'
let kind' = kindOf cmd''
let vars = (cmdKind := kind'):(propsOf cmd'')
vars'= map (\p -> (attrName p, p)) vars
-- update world
{-# SCC "exp/putWorld" #-}put $ w { cmd = cmd'', cmdVars =
M.fromList vars' }
-- move on
{-# SCC "processCbks" #-}processCallbacks
{-# SCC "exp/if" #-}if elem kind' (skip w)
then tracecmd cmd'' >> expect kind -- keep going
else match kind cmd''
--
http://wagerlabs.com/
More information about the Haskell-Cafe
mailing list