【问题标题】:heap memory buildup with xml-conduit parseBytes使用 xml-conduit parseBytes 建立堆内存
【发布时间】:2019-03-29 12:38:52
【问题描述】:

我正在使用 xml-conduit 的流接口 https://hackage.haskell.org/package/xml-conduit-1.8.0/docs/Text-XML-Stream-Parse.html#v:parseBytes 解析一些相当大的 XML 文件,但我看到了这种内存堆积(这里是一个小测试文件):

顶级用户在哪里:

实际数据不应该占用那么多堆——如果我序列化并重新读取,驻留内存使用量是千字节而不是这里的兆字节。

我设法重现此的最小示例:

{-# LANGUAGE BangPatterns      #-}
{-# LANGUAGE OverloadedStrings #-}

module Main where

import           Control.Monad
import           Control.Monad.IO.Class
import           Data.Conduit
import           Data.Conduit.Binary    (sourceFile)
import qualified Data.Conduit.List      as CL
import           Data.Text              (Text)
import           Text.XML.Stream.Parse

type Y = [(Text, Text)]

main :: IO ()
main = do
  res1 <- runConduitRes $
          sourceFile "test.xml"
          .| Text.XML.Stream.Parse.parseBytes def
          .| parseMain
          .| CL.foldM get []
  print res1

get :: (MonadIO m, Show a) => [a] -> [a] -> m [a]
get acc !vals = do
 liftIO $! print vals           -- this oughta force it?
 return $! take 1 vals ++ acc

parseMain = void $ tagIgnoreAttrs "Period" parseDetails

parseDetails = many parseParam >>= yield

parseParam = tag' "param" parseParamAttrs $ \idAttr -> do
  value <- content
  return (idAttr, value)

parseParamAttrs = do
  idAttr <- requireAttr "id"
  attr "name"
  return idAttr

【问题讨论】:

    标签: haskell memory-leaks xml-conduit


    【解决方案1】:

    如果我将 get 更改为仅返回 ["hi"] 或其他内容,我不会得到积累。因此,返回的文本似乎保留了对它们所在的较大文本的一些引用(例如,零拷贝切片,参见https://hackage.haskell.org/package/text-0.11.2.0/docs/Data-Text.html#g:18 处的评论),因此即使我们正在使用,其余文本也不能被垃圾收集只有很小的部分。

    我们的解决方法是在我们想要产生的任何属性上使用Data.Text.copy

    someattr <- requireAttr "n"
    yield (T.copy someattr)
    

    这让我们可以在几乎恒定的内存使用情况下进行解析。

    (如果我们想节省更多内存,我们可能会考虑使用https://markkarpov.com/post/short-bs-and-text.html#shorttext。)

    【讨论】:

      猜你喜欢
      • 2012-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-07
      相关资源
      最近更新 更多