【问题标题】:Garbage collection of pointers / foreign pointers during initialization初始化期间指针/外部指针的垃圾收集
【发布时间】:2020-02-13 09:10:35
【问题描述】:

我正在使用来自Data.ByteString.InternalmallocByteString 创建一个缓冲区。

在写入时,有时我可能会意识到我没有分配足够的内存,所以我分配了一个更大的缓冲区并改用它。 这个过程(重新分配、复制、忘记旧的 ptr)可能会发生很多次。

{-# LANGUAGE TypeApplications #-}
import Foreign.Ptr
import Foreign.ForeignPtr
import Foreign.Storable
import qualified Data.ByteString.Internal as BSI


test :: IO ()
test = do
  let capacity = 1024
  foreignPtr <- BSI.mallocByteString capacity
  withForeignPtr foreignPtr $ \ptr -> do
    poke @Word8 ptr 0
    poke @Word8 (ptr `plusPtr` 1) 1
    poke @Word8 (ptr `plusPtr` 2) 2
    poke @Word8 (ptr `plusPtr` 3) 3
    -- etc

    -- oops, 1024 bytes isn't going to be enough
    foreignPtr' <- BSI.mallocByteString (capacity * 2)
    withForeignPtr foreignPtr' $ \ptr' -> do
      BSI.memcpy ptr ptr' capacity

      -- poke ptr', poke ptr', poke ptr'

我的问题是:一旦我将内容从ptr 复制到ptr',旧的ptrforeignPtr 会发生什么?

即使withForeignPtr 延续仍在执行,它是否可以用于垃圾回收? 我需要以某种方式释放它吗?

我担心,如果我必须重新分配 10 次,我将有 9 个缓冲区占用不必要的内存。

【问题讨论】:

  • 我不是这些库的专家,但我认为在您离开withForeignPtr 之前不会忘记foreignPtr。
  • 看来你可以使用finalizeForeignPtr 强制释放一个。

标签: haskell memory garbage-collection ghc


【解决方案1】:

我已经重组了代码,以便在缓冲区已满时退出withForeignPtr然后重新分配/复制:

test2 :: IO ()
test2 = do
  let capacity = 1024
  foreignPtr <- BSI.mallocByteString capacity
  withForeignPtr foreignPtr $ \ptr -> do
    poke @Word8 ptr 0
    poke @Word8 (ptr `plusPtr` 1) 1
    poke @Word8 (ptr `plusPtr` 2) 2
    poke @Word8 (ptr `plusPtr` 3) 3
    -- etc

    -- oops, 1024 bytes isn't going to be enough
    return ()

  foreignPtr' <- BSI.mallocByteString (capacity * 2)
  withForeignPtr foreignPtr' $ \ptr' -> do
    withForeignPtr foreignPtr $ \ptr ->
      BSI.memcpy ptr ptr' capacity

    poke @Word8 (ptr' `plusPtr` capacity) 0
    poke @Word8 (ptr' `plusPtr` (capacity + 1)) 1
    poke @Word8 (ptr' `plusPtr` (capacity + 2)) 2

我相信,这样,GC就能清理旧指针了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-07
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    • 1970-01-01
    • 2011-04-10
    相关资源
    最近更新 更多