首页 > 解决方案 > Ruby:读取大型 JSON 文件而不会在 JSON 中发生内存泄漏

问题描述

我有一个需要解析为 JSON 文件的大字符串。使用常规 JSON gem、Yajl、Yajl-FFI 和 Oj 解析 JSON 导致在解析 JSON 文件后泄漏数百 MB 的内存,即使在GC.start多次调用之后也是如此。

在确保没有内存泄漏的同时从大字符串中解析 JSON 的最佳方法是什么?

我的代码:

Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8

require 'json'

# Obtaining the PID to find RAM usage
PID = `ps -ef | grep readFileTest`.split()[1].strip()
puts "PID: ["+ PID + "]"

def readFile(filePath)
  return File.read(filePath)
end

def writeFile(fileContent, filename)
  f = File.new(filename, "w")
  f.write(fileContent)
  f.close
end

def outRAM()
    puts "RAM: [" +`echo $(pmap #{PID} | grep total)`.strip() + "]"
end

puts "Pre read"
outRAM()

a = readFile('/CI_Pipeline/Profiles/JSONValues/JEF_TC3.json')
puts "After read"
outRAM()

b = JSON.parse(a)
puts "after json parse"
outRAM()

myfile = File.open('testfile.txt',"w");
puts "after opening file"
outRAM()

myfile.write(b);
puts "after write"
outRAM()

myfile.close;
puts "after close"
outRAM()


a = nil
b = nil
c = nil


for i in 0..4
    GC.start
    sleep(1)

    puts "After GC clean:"
    outRAM()
end

输出:

PID: [10516]
Pre read
RAM: [total 45948K]
After read
RAM: [total 73564K]
after json parse
RAM: [total 332196K]
after opening file
RAM: [total 332196K]
after write
RAM: [total 453976K]
after close
RAM: [total 453976K]
After GC clean:
RAM: [total 393144K]
After GC clean:
RAM: [total 393144K]
After GC clean:
RAM: [total 393144K]
After GC clean:
RAM: [total 393144K]
After GC clean:
RAM: [total 393144K]

使用上述替代方法进行 JSON 解析时,输出几乎相同。读取完成后可以做些什么来减少内存使用。我发现消除内存使用的唯一方法是杀死整个父进程。

标签: jsonrubysinatra

解决方案


推荐阅读