由于 iOS 系统对 Network Extension 进程有着严格的内存使用限制(目前版本为 50MB),Surge 在运行过程中可能因为瞬间的内存超限导致被系统停止。
正确情况下,绝大多数用户都不会遇到该问题。但是由于存在该硬性限制,有以下几种原因可能导致该问题发生:
如果 Surge 在短时间内遭遇了巨量的 app 请求,可能导致内存突发超限。在 Surge 的终止日志中,可以看到有大量的活跃请求(至少数百条以上)。
如果在配置加入特别多的配置项目(包含由模块注入的配置),会导致该问题在正常使用下容易出现,曾经有发现用户在 [Host] 中配置了 10000+ 条内容。由于主配置中内的内容均会被直接加载进内存,所以请勿在配置中加入巨量的条目。如果是规则需求可以使用 RULE-SET。
使用了 JSC 脚本,JSC 脚本引擎由于运行于 Surge Network Extension 进程内,且 JSC 引擎并未为内存占用所优化,一旦使用了 JSC 脚本,便会占据大量的内存,导致容易出现内存问题,请避免使用。(DNS 脚本默认使用 JSC 运行)
对于基于UDP 的代理协议(WireGuard, Hysteria 2 和 TUIC),由于 UDP 的流控不由 kernel space 处理,若线路情况较差,或者 Hysteria 2 配置了不合理的 download-bandwidth 参数,可能导致瞬间接收到的 UDP 数据包过多而内存超限。通常该问题仅在进行测速等高压力场景下会出现。
需要注意的是,Surge 内存占用分为持续占用和突发占用,持续占用可以在 Surge 的日志中观察到(搜索 memory usage),通常来说,Surge 持续占用的内存会稳定在 20MB 以下。上述 2、3 属于持续占用,1、4 属于突发占用。
持续占用的内存越多,留给处理请求时的突发占用的空间就越小,就越可能出现因为突发超限导致被终止的问题。