我有一个基于Kemal的RESTful web服务,返回“非常大”的JSON数据块(大小从10到17M不等),它是由“大”Hash结构的to_json方法生成的。
根据GC警告信息,我的代码“可能导致内存泄漏”,而我的自己的测量结果显示,在应用程序运行期间内存正在“泄漏”。
因此,我认为,手动释放为Hash及其JSON字符串表示分配的内存将是很好的,但我不知道如何做到这一点:我的使用文档不良的GC.free方法进行实验并不成功,也不知道继续研究方向...
请告诉我怎样避免内存泄漏?
您可以在这里查看我非常简单的应用程序的版本(实际上它是在封闭的公司网络段内开发的)https://github.com/DRVTiny/Druid/blob/master/src/druid_mp.cr 导致内存泄漏的代码:
根据GC警告信息,我的代码“可能导致内存泄漏”,而我的自己的测量结果显示,在应用程序运行期间内存正在“泄漏”。
因此,我认为,手动释放为Hash及其JSON字符串表示分配的内存将是很好的,但我不知道如何做到这一点:我的使用文档不良的GC.free方法进行实验并不成功,也不知道继续研究方向...
请告诉我怎样避免内存泄漏?
您可以在这里查看我非常简单的应用程序的版本(实际上它是在封闭的公司网络段内开发的)https://github.com/DRVTiny/Druid/blob/master/src/druid_mp.cr 导致内存泄漏的代码:
get "/service/:serviceid" do |env|
if (svcid = env.params.url["serviceid"]) && svcid.is_a?(String) && svcid =~ /^s?\d+$/
druid.svc_branch_get((svcid[0] == 's' ? svcid[1..-1] : svcid).to_i).to_json
else
halt env, status_code: 404, response: %q({"error": "Wrong service identificator"})
end
rescue ex
halt env, status_code: 503, response: {"error": "Unhandled exception #{ex.message}"}.to_json
end
P.S. 在每个用户请求后,我插入了after_all钩子执行GC.collect。不知道,也许这可以解决我的问题(但我认为这根本不是正确的方法)。
更新:在我将GC.collect添加到after_all Kemal钩子之后,内存泄漏消失了。但全局GC.collect可能太慢了,并且我知道它会阻止所有纤维和socket.accept()。如果我错了,请告诉我。