我有一个基于Kemal的RESTful Web服务,返回"非常大"(大小从10到17M)的JSON数据块,这是由"大"Hash结构的to_json方法生成的.
根据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
Run Code Online (Sandbox Code Playgroud)
PS我在每个用户请求后插入了执行GC.collect的after_all钩子.不知道,也许这可以解决我的问题(但我认为这根本不是正确的方法).
UPD:在我将GC.collect添加到after_all Kemal钩子后 - 内存泄漏消失了.但是全局GC.collect可能太慢了,据我所知,它会阻塞所有光纤和socket.accept().如果我弄错了,请告诉我.
我正在编写一些web api,它以JSON格式返回数据.
对于所有传入的URL,如果缓存周期没有到期,我需要从缓存返回一些结果.
这种逻辑对所有URL都是通用的.
题:
如何在Mojolicious :: Lite中为所有传入的URL实现一些通用逻辑?
我试着这样做
any '/:bar' => [bar => qr/.+/] => sub {
# ...
# Return JSON object immediately from cache if it is applicable
# ...
}
Run Code Online (Sandbox Code Playgroud)
但是这会导致非常长的页面加载和
Template "bar.html.ep" not found
Run Code Online (Sandbox Code Playgroud)
在morbo日志中(但是经过很长时间的延迟后,最终会执行"/ target"处理程序).
我是Mojo的完美新手,所以任何帮助都将受到赞赏
谢谢!
在这种情况下,如何识别是否有变量或文字被传递给函数f()?
如何实现pass_as_constant()检查(参见下面的代码)?
sub f {
my $refStr=\$_[0];
return if passed_as_constant($_[0]) and !defined(wantarray);
substr(${$refStr}, 0, 1)='D';
# return the copy of the string if it was passed
# to the function as constant aka "literally" or if copying was explicitly requested by the left-side context
(passed_as_constant($_[0]) or defined(wantarray)) and return ${$refStr};
}
# Argument was passed literally and function called without left-side context - we may simply "do nothing"
f('Bingo!');
# Argument was passed literally and left-side context is here. We …Run Code Online (Sandbox Code Playgroud) 它很糟糕,perl中的grep函数无法识别"布尔"上下文,因为在Perl中根本没有"布尔"上下文.
所以,如果我做这样的事情
print "matched\n" if grep { print "$_\n"; $_&1 } 1..31
Run Code Online (Sandbox Code Playgroud)
将打印从1到31的数字而不是仅打印"1",这足以在"if"中获得"true"结果.
为了避免这种行为,我必须做一些可怕的事情:
print "matched\n" if do { my $fl; $_&1 and $fl=1, last for 1..31; $fl }
Run Code Online (Sandbox Code Playgroud)
也许它可以用最简单的方式完成?是否有一些在CPAN上实现"布尔grep"的快速XS代码?