Erlang进程信息中的二进制文件重复

时间:2018-08-20 18:34:40

标签: erlang elixir

我试图通过对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是唯一的,并且可以用来简化列表?这是解决我的问题的正确方法吗?

0 个答案:

没有答案