You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Erlang如何限制进程内存?spawn_opt参数badarg报错求解

如何正确使用Erlang的spawn_opt限制进程堆内存

我来帮你搞定这个问题——你碰到的badarg错误本质上是max_heap_size参数格式或者spawn_opt调用参数出了问题,咱们一步步梳理修正。

先分析你的错误根源

从你给出的崩溃日志来看,spawn_opt被调用时传入的参数是maxMemCheck,fib,"\n",[...],这明显和你代码里写的printfib/1、参数[10]不符,大概率是实际运行时误传了参数(比如把函数名写错,或者传了字符串而非整数)。另外,还有一个可能是Erlang版本兼容性问题:旧版OTP(20及之前)不支持用map格式配置max_heap_size,必须用元组格式,这也会触发badarg。

修正后的代码示例

兼容新旧版本的元组格式写法

如果你的Erlang版本比较旧,或者想保证最大兼容性,用元组格式配置max_heap_size:

-module(maxMemCheck).
-export([fib/1, printfib/1]).
-export([main/0]).

printfib(N) -> 
    Res = maxMemCheck:fib(N), 
    io:fwrite("~w ~w~n", [N, Res]).

fib(0) -> 0;
fib(1) -> 1;
fib(N) when N > 0 -> fib(N-1) + fib(N-2).

main() -> 
    % 元组格式:{size, KillFlag, ErrorLoggerFlag}
    spawn_opt(maxMemCheck, printfib, [10], [{max_heap_size, {300, true, true}}]).

OTP 21+支持的map格式写法

如果你用的是较新版本的Erlang(OTP 21及以上),map格式是完全可行的,但要确保参数传递绝对正确:

main() -> 
    spawn_opt(maxMemCheck, printfib, [10], [{max_heap_size, #{size => 300, kill => true, error_logger => true}}]).

关键注意事项

  1. 内存单位是「词」不是字节:max_heap_size的size参数单位是Erlang的「词(word)」,64位系统下每个词是8字节。你设置的300词仅约2.4KB,这个限制非常严格,fib(10)的递归调用可能瞬间就触发内存上限导致进程被杀死,测试时可以调大到比如10000(约80KB)。
  2. 参数传递必须精准:一定要确保spawn_opt的函数名、参数列表完全匹配目标函数的arity(比如printfib/1必须传一个整数参数,不能传字符串),不然必然触发badarg。
  3. 无需依赖gen_server:你完全不需要用gen_server来实现内存限制,spawn_opt的max_heap_size参数本身就可以直接完成这个需求——当进程堆内存超过限制时,kill => true会直接终止进程,error_logger => true会在控制台输出对应的错误日志,方便你追踪问题。

测试方法

编译并运行修正后的代码:

erlc maxMemCheck.erl
erl -noshell -s maxMemCheck main -s init stop

如果设置的size足够小,你会看到进程被杀死的日志;如果size足够大,会正常输出10 55的结果。

内容的提问来源于stack exchange,提问作者yoda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:07:00