Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Erlang进程信息中存在重复的二进制文件_Erlang_Elixir - Fatal编程技术网

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

Erlang进程信息中存在重复的二进制文件,erlang,elixir,Erlang,Elixir,我试图通过对process.info(pid,:binary)的结果求和来计算一个进程保留了多少二进制内存,但它给出了不准确的结果。在一台有128GB内存的机器上,它说一个进程使用了超过1TB的内存 我想我已经把问题归结到多次返回包含相同二进制文件的列表的Process.info 这是一个长生不老药脚本,演示了我所看到的。“垃圾文件”是我创建的一个文件,它有一堆JSON对象,每行一个对象 result = Stream.iterate(0, & &1 + 1) |>

我试图通过对
process.info(pid,:binary)
的结果求和来计算一个进程保留了多少二进制内存,但它给出了不准确的结果。在一台有128GB内存的机器上,它说一个进程使用了超过1TB的内存

我想我已经把问题归结到多次返回包含相同二进制文件的列表的
Process.info

这是一个长生不老药脚本,演示了我所看到的。“垃圾文件”是我创建的一个文件,它有一堆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是唯一的,并且可以用于删除列表中的重复数据,这样安全吗?这是解决我的问题的正确方法吗?

旁注:你在滥用管道操作员
Enum.map(binaries,&elem(&1,1))|>Enum.sum()
应在此处和任何地方写成
binaries |>Enum.map(&elem(&1,1))|>Enum.sum()