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

托斯滕·舍宁

该问题与以前有关Perl的内存处理问题答案有关我了解到,可以通过undef在可用标量上显式使用该函数并使用Devel::PeekDevel::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中的变量关联的内存。

您还忽略了以下事实:许多运算符都有一个关联变量(称为“目标”),在该变量中他们返回结果。

方法1

清除所有这些变量的一种简单方法是有选择地清除符号表(%::)。这将有效地“卸载”每个模块。确保不清除核心组件(perl -E'say for sort keys %::')。并且不要忘记清除%INC以便可以重新加载模块。

如果要清除符号表是您要采取的方法,则%::尽早制作快照并在需要清除符号时还原该快照的风险和时间会减少

方法2

如果您不想重新加载模块,则可以尝试找到每个子模块,并先定义其变量,然后再解除其操作变量。

潜艇的变种存在于其衬垫内方便地,操作码目标也是如此。子体验到的每个递归级别都有一块垫子。

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

捕获的变量和our变量应保持不变。可以检测填充项是否是其中之一。(再次,请参阅PadWalker。)

(显然,您也可以考虑释放潜水艇的额外垫!)

您如何找到所有潜艇?好吧,浏览符号表将为您提供大部分信息。寻找匿名者会比较棘手。

方法3

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


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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在不指定final的情况下访问变量?

如何在不破坏列表的情况下释放指针?

如何在没有内存分配的情况下循环访问ArrayBlockingQueue(GC延迟)

Perl:如何在不创建副本的情况下将数组引用转换为数组

Perl:如何在不创建数组副本的情况下取消引用数组?

如何在不运行函数的情况下将其分配给变量?

如何在不使用分配的情况下访问类中的私有变量?

在Perl中如何在不使用XS的情况下写入调用方变量?

嵌套函数如何在以后不声明的情况下访问Javascript中的变量?

C#如何在不创建实例的情况下访问变量?

如何在不继承的情况下访问组件的属性

如何在不访问Windows的情况下删除grub

如何在不使用动态分配器的情况下动态访问内存,包括 brk、sbrk 和 mmap

如何在不更改变量的情况下递归

如何在不创建变量的情况下使用 Javascript?

如何在不破坏循环的情况下返回变量?

如何在不使用第三个变量的情况下交换两个Perl变量?

如何在不传递参数或放置全局变量的情况下从其他范围访问变量?

如何在不接触未更改文件的情况下替换Perl中现有文件中的字符串

如何在不丢失程序退出代码的情况下使用Test :: More测试perl程序中的子程序?

如何在不耗尽内存的情况下读取tsv文件并将其存储为hdf5?

Perl:在不创建新变量的情况下测试正则表达式

如何在不释放鼠标键的情况下更改所选文本

如何在不释放Lisp的情况下抓住读写锁?

如何在不释放元素的情况下从 unordered_set 中删除元素

perl-如何在不使用变量进行比较的情况下替换数组中的空值?

在 Perl 中,如何在不使用模块的情况下判断字符串是否为数字?

如何在不创建其他变量的情况下修复“创建一个在仍在使用时被释放的临时文件”?

如何在不更改全局变量的情况下更改分配给全局变量值的局部变量?