gpt4 book ai didi

erlang - 为什么我的脚本会使解释器崩溃?

转载 作者:行者123 更新时间:2023-12-05 09:20:33 28 4
gpt4 key购买 nike

我有一个读取 csv 文件 (100M) 的小程序。问题是我的程序使 Erlang 解释器崩溃:

Crash dump was written to: erl_crash.dump
eheap_alloc: Cannot reallocate 3563526520 bytes of memory (of type "heap").
Aborted

程序如下:

readlines(FileName) ->
{ok, Device} = file:open(FileName, [read]),
try get_all_lines(Device)
after file:close(Device)
end.


get_all_lines(Device) ->
case io:get_line(Device, "") of
eof -> [];
Line -> [Line | get_all_lines(Device)]
end.

我这样做:

Path="...csv".
Lines=tut6:readlines(Path).

这会导致崩溃。

谁能告诉我问题出在哪里?也许我的程序有问题?如何避免崩溃?

提前致谢

最佳答案

你知道 3563526520 是 3.3 GB 吗?你的系统有多少内存?巨大的内存消耗源于您选择了最不理想的算法来读取行:

  1. 在对它们采取行动之前,您尝试将所有行读入内存
  2. 您选择将文本表示为列表,从文件中读取的每个字符使用 8 个字节(或 64 位系统上的 16 个字节)
  3. 您不使用尾递归,这意味着编译器无法优化您的代码以提高内存效率

因此,修复代码:

  1. 一次读取一行,然后解析和处理它并存储为 Erlang 术语而不是原始输入数据
  2. 按照 Hynek -Pichi- Vychodil 的建议,将行作为二进制文件阅读
  3. 使读取文件的函数成为尾递归的

Learn You Some Erlang如果您想知道如何正确实现此类函数,请参阅有关尾递归函数的精彩讨论。

如果函数以尾递归方式编写,整个算法可能如下所示:

get_all_lines(Device) ->
get_all_lines(Device, []).

get_all_lines(Device, List) ->
case io:get_line(Device, "") of
eof ->
lists:reverse(List);
Line ->
Data = process_line(Line),
get_all_lines(Device, [Data | List])
end.

关于erlang - 为什么我的脚本会使解释器崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37487556/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com