该问题与以前有关Perl的内存处理问题的答案有关。我了解到,可以通过undef
在可用标量上显式使用该函数并使用Devel::Peek
或Devel::Size
或这样的人可以看到为标量分配了多少内存来释放Perl中的内存。在所有这些情况下,调试的标量均在其范围内使用。
但是是否有可能在Perl解释器的级别上调试诸如变量范围之外的已分配内存之类的事情?诸如搜索当前解释器中所有为标量的“事物”并打印其关联数据(例如当前值等)的所有已分配内存?
如果是这样的话,如果一个人已经掌握了该信息,那它甚至可以释放已知的内存吗?就像调用undef
标量一样,但是没有标量,则是更低级别的东西,例如的那些“物”输出Devel::Peek
。
我正在考虑的是在请求后执行mod_perl清理处理程序,扫描当前的mod_perl解释器以获取大块数据,然后手动释放它们。仅仅因为我认为分配的大块数据不再有用了,即使Perl认为不是这样:
最后,也许最大的胜利就是内存的重用:在对Perl子例程的调用中,首次使用变量时会为变量进行内存分配。变量的后续使用可能会分配更多的内存,例如,如果标量变量需要比以前容纳更长的字符串,或者数组中添加了新元素。作为一种优化,Perl会挂在这些分配上,即使它们的值“超出范围”。
https://perl.apache.org/docs/2.0/user/intro/overview.html#Threads_Support
我可以找到许多有关低级内存访问的监视和调试程序包,但是还没有提示如何undef
在Perl中调用诸如低级Perl结构上的函数之类的东西。没有任何XS或此类武器根本不可能...
是否可以调试变量范围之外的已分配内存之类的东西
确实没有任何此类记忆。肯定需要在变量之外分配的任何内存。正如您自己指出的那样,分配给变量的内存构成了大多数“浪费”的空间。
但是还没有提示如何在Perl中的某些低级Perl结构上调用诸如undef函数之类的东西。
这是因为没有这样的结构。
就像调用
undef
标量一样,但是没有标量,则是更低级的东西,例如在Devel :: Peek的“物”输出上。
杰韦利::皮克的唯一功能,Dump
,输出的东西中的变量。就像您说的那样,undef
您想要清除这些内容。
从上面可以明显看出,您想知道如何释放与subs中的变量关联的内存。
您还忽略了以下事实:许多运算符都有一个关联变量(称为“目标”),在该变量中他们返回结果。
清除所有这些变量的一种简单方法是有选择地清除符号表(%::
)。这将有效地“卸载”每个模块。确保不清除核心组件(perl -E'say for sort keys %::'
)。并且不要忘记清除%INC
以便可以重新加载模块。
如果要清除符号表是您要采取的方法,则%::
尽早制作快照并在需要清除符号时还原该快照的风险和时间会减少。
如果您不想重新加载模块,则可以尝试找到每个子模块,并先定义其变量,然后再解除其操作变量。
潜艇的变种存在于其衬垫内。方便地,操作码目标也是如此。子体验到的每个递归级别都有一块垫子。
给定一个对子的引用,您可以在子垫中找到变量。您可以参考PadWalker以获取有关如何执行此操作的示例。您实际上不能使用PadWalker,因为即使每个变量名有多个,PadWalker只会为每个变量名返回一个变量(由于使用同一个名称声明了多个变量,或者由于递归)。
捕获的变量和our
变量应保持不变。可以检测填充项是否是其中之一。(再次,请参阅PadWalker。)
(显然,您也可以考虑释放潜水艇的额外垫!)
您如何找到所有潜艇?好吧,浏览符号表将为您提供大部分信息。寻找匿名者会比较棘手。
最有效的方法是简单地终止mod_perl线程/进程。将自动产生一个新的干净的。它也是最简单的实现,因为它只是配置更改(设置MaxRequestsPerChild
为1
)。
浪费的内存的另一种形式是内存泄漏。这是另一个大问题,所以我没有涉及。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句