微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Perl:如何在不访问Perl变量的情况下释放为标量分配的内存?

这个问题与Perl的 answerquestion about memory handling有关.我已经知道可以通过在可用标量上显式使用undef函数并使用Devel :: Peek或Devel :: Size来释放Perl中的内存,或者这样可以看到为标量分配了多少内存.在所有这些情况下,调试的标量都在其范围内使用.

但是,是否可以在变量范围之外调试分配内存之类的东西,只是在Perl解释器的层次上?比如为当前解释器中的标量搜索所有“事物”的所有已分配内存并打印其相关数据(如当前值等)?

如果是这样的话,如果一个人已经掌握了这些信息,那么是否能够释放已知的记忆?就像在标量上调用undef一样,但没有标量,更低级别的东西,比如Devel :: Peek的那些“东西”输出.

我正在考虑的是在请求之后执行mod_perl清理处理程序,扫描当前mod_perl解释器以获取大块数据并手动释放它们.仅仅因为我认为大块分配的数据不再有用,即使Perl认为不是这样:

Finally and perhaps the biggest win is memory re-use: as calls are made into Perl subroutines,memory allocations are made for variables when they are used for the first time. Subsequent use of variables may allocate more memory,e.g. if a scalar variable needs to hold a longer string than it did before,or an array has new elements added. As an optimization,Perl hangs onto these allocations,even though their values “go out of scope”.

https://perl.apache.org/docs/2.0/user/intro/overview.html#Threads_Support

我可以找到很多关于低级内存访问的监视和调试包,但是没有提示如何在Perl中的某些低级Perl结构上调用类似undef函数内容.没有任何XS或其他可能根本不可能……

解决方法

is it possible to debug things like allocated memory outside the scope of variables

真的没有这样的记忆.肯定需要在变量之外分配的任何内存.正如你自己指出的那样,它是为构成最“浪费”空间的变量分配的内存.

but no hint yet how one Could call something like the undef function on some low level Perl struct in Perl.

这是因为没有这样的结构.

Just like calling undef on a scalar,but without the scalar,something more low level,like on those “things” output of Devel::Peek.

Devel :: Peek唯一的功能,Dump,输出变量中的东西.就像你说的那样,undef是你想要清除它们的东西.

从上面可以看出,你很想知道如何释放与subs中变量相关的内存.

您还忽略了这样一个事实,即许多运算符都有一个关联变量(称为“目标”),在该变量中返回结果.

方法1

清除所有这些变量的一种简单方法是选择性地清除符号表(%::).这将有效地“卸载”每个模块.一定不要清除核心组件(perl -E’say用于排序键%::’).并且不要忘记清除%INC,以便可以重新加载模块.

如果清除符号表是您想要采用的方法,那么在早期拍摄%::的快照时可能风险较小且耗时,并且在清除符号时还原该快照.

方法2

如果你不想重新加载模块,你可以尝试找到每个子,并取消他们的变量,然后取消他们的操作的变量.

一个子的变量存在于其pads内.方便的是,操作码目标也是如此.对于子经历的每个递归级别都有一个填充.

给定对sub的引用,您可以在子垫中找到变量.有关如何执行此操作的示例,请参阅PadWalker.你实际上不能使用PadWalker,因为它只为每个变量名返回一个变量,即使有多个变量(由于多个变量被声明为具有相同的名称,或者由于递归).

捕获的变量和我们的变量应保持不变.可以检测填充条目是否是其中之一. (再次参考PadWalker.)

(显然,你也可以考虑释放sub的额外垫!)

你怎么找到所有潜艇?那么,导航符号表将为您提供大部分.寻找一个人将会更棘手.

方法3

最有效的方法是简单地终止mod_perl线程/进程.将自动生成一个新的干净的.它也是最简单的实现,因为它只是一个配置更改(将MaxRequestsPerChild设置为1).

浪费内存的另一种形式是内存泄漏.这是另一个大问题,所以我没有触及它.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐