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}}]).
关键注意事项
- 内存单位是「词」不是字节:
max_heap_size的size参数单位是Erlang的「词(word)」,64位系统下每个词是8字节。你设置的300词仅约2.4KB,这个限制非常严格,fib(10)的递归调用可能瞬间就触发内存上限导致进程被杀死,测试时可以调大到比如10000(约80KB)。 - 参数传递必须精准:一定要确保
spawn_opt的函数名、参数列表完全匹配目标函数的arity(比如printfib/1必须传一个整数参数,不能传字符串),不然必然触发badarg。 - 无需依赖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
相关产品推荐
相关产品推荐

