假設我有幾個非常大的向量。它們存盤在磁盤上。我需要通過讀取每個將它們放入記憶體的檔案來單獨訪問它們。我會在單個向量上執行一些功能,然后轉到下一個我需要訪問的向量。每次我需要訪問不同的向量時,我都需要能夠指示記憶體中的每個向量進行垃圾收集。如果在我的程式中宣告我必須稍后通過參考從磁盤讀取向量的相同函式名稱來再次訪問同一個向量,我不確定是否performMajorGC會確保該向量將被垃圾收集。在這種情況下,我會再次將它讀入記憶體,使用它,然后垃圾收集它。在對從同一檔案中讀取的向量使用相同的函式名稱時,如何確保它是車庫收藏?
將不勝感激任何建議謝謝
回應丹尼爾瓦格納:
myvec x :: Int -> IO (Vector (Vector ByteString))
myvec x = do let ioy = do y <- Data.ByteString.Lazy.readFile ("data.csv" (show x))
guard (isRight (Data.Csv.decode NoHeader y))
return y
yy <- ioy
return (head $ snd $ partitionEithers [Data.Csv.decode NoHeader yy])
myvecvec :: Vector (IO (Vector (Vector ByteString)))
myvecvec = generate 100 (\x -> myvec x)
somefunc1 :: IO (Vector (Vector ByteString)) -> IO ()
somefunc1 iovv = do vv <- iovv
somefunc1x1 vv :: Vector (Vector ByteString) -> IO ()
-- somefunc2 和 3 一樣
oponvec :: IO ()
oponvec = do somefunc1 (myvecvec ! 0)
performGC
somefunc2 (myvecvec ! 1)
performGC
somefunc3 (myvecvec ! 0)
uj5u.com熱心網友回復:
您可以使用弱指標進行測驗,如下所示:
import qualified Data.Vector.Unboxed as V
import System.Mem.Weak
import System.Mem
main :: IO ()
main = do
let xs = V.fromList [1..1000000:: Int]
wkp <- mkWeakPtr xs Nothing
performGC
xs' <- deRefWeak wkp
print xs'
在我的系統上列印Nothing這意味著向量已被釋放。但是,我不知道 GHC 是否保證會發生這種情況。
這是一個檢查@amalloy 建議的程式:
import qualified Data.Vector.Unboxed as V
import Control.Monad
import Data.Word
{-# NOINLINE newLarge #-}
newLarge :: Word8 -> V.Vector Word8
newLarge n = V.replicate 5000000000 n -- 5GB
main :: IO ()
main = forM_ [1..10] $ \i -> print (V.sum (newLarge i))
這在我的機器上正好使用了 5GB,這表明從來沒有同時分配兩個大向量。
uj5u.com熱心網友回復:
每次我需要訪問不同的向量時,我都需要能夠指示記憶體中的每個向量進行垃圾收集。
你?為什么?如果僅僅是因為它們很大并且您擔心將向量放入記憶體中,那么請不要擔心。如果需要記憶體空間,而物件無法訪問,那么垃圾收集器會拾取它。如果不需要記憶體空間,則無需執行任何操作。如果物件是可訪問的,那么運行 GC 將無濟于事。因此,在 GC 中手動干預沒有任何好處。
如果你想 GC 它是出于釋放記憶體以外的其他原因,你需要在問題中解釋這一點,因為這個目標肯定會影響答案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/446776.html
上一篇:僅從Python中的父類繼承型別
