[GHC] #13630: ByteString pinned memory can be leaky
GHC
ghc-devs at haskell.org
Sun Apr 30 01:17:07 UTC 2017
#13630: ByteString pinned memory can be leaky
-------------------------------------+-------------------------------------
Reporter: nh2 | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone:
Component: Runtime | Version: 8.0.1
System |
Keywords: | Operating System: Unknown/Multiple
Architecture: | Type of failure: None/Unknown
Unknown/Multiple |
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Rev(s): | Wiki Page:
-------------------------------------+-------------------------------------
My question on IRC:
{{{
How does memory allocation for pinned blocks work?
Let's say pinned blocks are 4KB in size, and I allocate first a 3 KB
ByteString A and then an 8-byte ByteString B.
Now I GC A, no longer need it.
Then according to
https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/GC/Pinned
"a single pinned object keeps alive the whole block in which it resides",
my small ByteString B keeps the entire block alive.
But what happens with the 3KB in the front of that block?
Will it be re-used by the next ByteString allocation (say 1KB)?
In other words, how smart is allocatePinned as an allocator?
}}}
The answer:
{{{
slyfox: nh2: allocatePinned it quite dump. it only allocated from free
tail space
}}}
{{{
nh2: slyfox: that sounds like a huge potential for memory leak then
slyfox: yes, fragmentation is quite bad for bytestrings
}}}
So it seems that I can get into the unfortunate situation where a super
short `ByteString` of a few bytes can waste an entire 4 KB block of
memory; some migth call this a leak.
One idea to solve it seems to be to change standard `ByteStrings` to not
pinned, and to allocate pinned ones explicitly when needed. This seems to
be an often-discussed topic and not trivial because many `ByteString`
functions are implemented using libc FFI functions.
However, it seems there will always be _some_ need for pinned memory, so
we should better have an efficient way to manage it in any case.
Efficient here means, for example, to re-use freed memory inside a block
instead of only using free tail space.
It seems that `jemalloc` has a feature to use given blocks of memory and
provide a `malloc()` functionality inside them:
https://stackoverflow.com/questions/30836359/jemalloc-mmap-and-shared-
memory
Perhaps this could be used to provide GHC with a simple method to use
pinned memory more efficiently?
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13630>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list