我试图通过对Process.info(pid, :binary)
的结果求和来确定一个进程占用了多少二进制内存,但这给了我错误的结果。在一台具有128GB RAM的计算机上,它表示一个进程正在使用超过1TB的内存。
我认为我已将问题归结为Process.info
,多次返回了包含相同二进制文件的列表。
这是一个Elixir脚本,用于演示我所看到的内容。 “ junk_file”是我创建的文件,其中包含一堆JSON对象,每行一个对象。
result =
Stream.iterate(0, & &1 + 1)
|> Stream.take(10_000)
|> Flow.from_enumerable(max_demand: 1)
|> Flow.flat_map(fn _ ->
File.read!("junk_file") |> String.split("\n")
end)
|> Enum.to_list()
system_binary_bytes =
:erlang.memory() |> Keyword.get(:binary)
{:binary, binaries} =
Process.info(self(), :binary)
binary_ids =
Enum.map(binaries, &elem(&1, 0))
binary_bytes =
Enum.map(binaries, &elem(&1, 1))
|> Enum.sum()
unique_binary_bytes =
Enum.uniq_by(binaries, fn {id, _, _} -> id end)
|> Enum.map(&elem(&1, 1))
|> Enum.sum()
unique_ids =
MapSet.new(binary_ids)
unique_ids_times_ref =
Enum.uniq_by(binaries, fn {id, _, _} -> id end)
|> Enum.map(& elem(&1, 2))
|> Enum.sum()
IO.puts("binary_ids #{Enum.count(binary_ids)}")
IO.puts("unique_ids #{Enum.count(unique_ids)}")
IO.puts("binary_bytes #{binary_bytes}")
IO.puts("unique_bytes #{unique_binary_bytes}")
IO.puts("unique_ids_times_ref #{unique_ids_times_ref}")
IO.puts("system_binary_bytes #{system_binary_bytes}")
Enum.count(result)
以下是示例运行的结果:
binary_ids 2166004
unique_ids 10003
binary_bytes 373817119944
unique_bytes 1725843360
unique_ids_times_ref 2166009
system_binary_bytes 1731508128
如您所见,重复了很多id,并且在对每个二进制文件进行二进制id重复数据删除后,对报告的每个二进制文件的内存求和,结果总计与系统总数非常接近。
是否可以安全地假定二进制ID是唯一的,并且可以用来简化列表?这是解决我的问题的正确方法吗?