初始化期间指针/外部指针的垃圾收集

问题描述 投票:1回答:1

我正在使用mallocByteString中的Data.ByteString.Internal创建缓冲区。

并且在写它时,有时我可能意识到我没有分配足够的内存,所以我分配了更大的缓冲区并改为使用它。此过程(重新分配,复制,忘记旧的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个缓冲区占用不必要的内存。

haskell memory garbage-collection ghc
1个回答
0
投票

我已经重组了代码,以便当缓冲区已满时我退出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将能够清理旧指针。

© www.soinside.com 2019 - 2024. All rights reserved.