我们在使用 Akka HTTP 构建的 Web 服务器上遇到了奇怪的内存行为。我们的架构是这样的:
- Web 服务器路由调用各种参与者,获取未来的结果并将其流式传输到响应
- 参与者调用非阻塞操作(使用期货),组合和处理从它们获取的数据并将结果传递给发送者。我们使用标准的 Akka 演员,实现其接收方法(不是 Akka 类型)
- 应用程序中的任何地方都没有阻止代码
当我在本地运行 Web 服务器时,一开始大约需要 350 MB。第一次请求后,内存使用量跃升至 430 MB 左右,并随着每个请求缓慢增加(使用 Mac 上的 Activity Monitor 进行监控)。但是GC不应该在每次请求后清理东西吗?处理后的内存使用量不应该再次为 350 MB 吗?
我还安装了YourKit java分析器,这是一个头记忆图
可见,一旦内存使用量增加,就再也回不去了,系统是无状态的。此外,当我从分析器手动运行 GC 时,它几乎什么都不做,只是内存使用量略有减少。我知道有些服务可能会在第一次请求后缓存东西,暂时消耗内存,但是 Akka Actors 或 Akka HTTP 内部有没有关于这个的策略?
我试图检查离 GC 最远的对象,但它只显示库类和内置类的 Akka,与我们的代码无关。
所以,我有两个问题:
- 消息处理后actor如何关闭资源并释放内存?你有过类似的经历吗?
- 有没有更好的方法来分析 Akka HTTP,它会告诉我使用离 GC 最远的分类的堆栈跟踪?
附带说明一下,是否建议在 Actors 内使用调度程序(在 Akka HTTP 服务器内运行)?当我这样做时,似乎内存使用量大幅增加,并且应用程序在 DEV 环境中运行我们的内存。
提前致谢,
阿米尔