我的问题是:
我有一个使用大量内存的perl脚本(由于缓存而导致的预期行为)。但是,我注意到我做的缓存越多,得到的速度越慢,并且该过程大部分时间都处于睡眠模式。
我认为预先为进程分配内存可能会加快性能。
有人有任何想法吗?
更新:
我想我在这里不是很清楚。我会以更清晰的方式提出问题:
我不是在寻找在perl脚本中预分配的方法。我不认为这会对我有所帮助。我感兴趣的是一种告诉操作系统为我的perl脚本分配X内存量的方法,这样它就不必与以后出现的其他进程竞争。
假设我无法逃避内存使用。虽然,我正在探索减少这种方法的方法,但不要期望那里有太大的改进。 仅供参考,我正在使用solaris 10机器。
答案 0 :(得分:4)
我从您的发布和评论中收集到的内容是:
很可能是eplanation:睡觉意味着等待资源可用。在这种情况下,资源最有可能是内存。使用vmstat 1命令进行验证。看看sr专栏。如果它一直超过~150,那么系统迫切需要释放页面来满足需求。这伴随着pi,po和fr列的高活动性。
如果确实如此,那么您最好的选择是:
预分配内存无济于事。在任何一种情况下,内存需求都会在某个时刻超过可用的主内存。然后,内核必须决定现在哪些页面需要在内存中,哪些页面可以被清除并重新用于更迫切需要的页面。如果所有正常需要的页面(工作集)超过主存储器的大小,则系统不断地将页面从二级存储器移动到另一个存储器(交换)。据说该系统正在颠簸,并且花费的时间不多于做有用的工作。除了添加内存或使用更少的内存之外,你无能为力。
答案 1 :(得分:2)
来自评论:
内存限制不是很严重,但内存占用很容易增加到GB,当我们有内存竞争过程时,它会变得非常慢。我想从操作系统中保留一些内存,这样即使有太多其他进程出现,颠簸也很少。 Jagmal
让我们采取不同的策略。特别是你的Perl脚本不是问题。相反,机器上的所有进程都消耗了太多内存,以便机器按配置处理。
你可以“保留”记忆,但这不会阻止颠簸。事实上,它可能会使问题变得更糟,因为操作系统不会知道您是使用内存还是仅将其保存以供日后使用。
我怀疑你正在受苦the tragedy of the commons。我是对的,有问题的机器上有很多其他用户吗?如果是这样,这更多的是社会问题,而不是技术问题。您需要的是某人(可能是系统管理员)介入并协调机器上的所有进程。他们应该找到最奢侈的记忆力,并与程序员合作,以降低系统资源的成本。此外,他们应该安排进程安排,以便资源分配有效。最后,他们可能需要获得更多或改进的硬件来处理预期的系统负载。
答案 2 :(得分:0)
您可能会问自己一些问题:
答案 3 :(得分:0)
查看http://metacpan.org/pod/Devel::Size
您还可以内联一个c函数来执行上述操作。
据我所知,你不能直接从Perl分配内存。您可以通过编写XS模块或使用我提到的内联C函数来解决这个问题。
答案 4 :(得分:0)
my @array;
$#array = 1_000_000; # pre-extend array to one million elements,
# http://perldoc.perl.org/perldata.html#Scalar-values
my %hash;
keys(%hash) = 8192; # pre-allocate hash buckets
# (same documentation section)
不熟悉你的代码,我会在这里冒昧地猜测这些技术不会为你的脚本提供新的高效率,但是预分配可能会有所帮助。 / p> 祝你好运!
- 道格拉斯亨特
答案 5 :(得分:0)
我最近重新发现了一个优秀的Randal L. Schwartz article,其中包括预先分配数组。假设这是您的问题,您可以测试预分配该代码的变体。但一定要测试结果。
脚本变慢,缓存更多的原因可能是thrashing。据推测,首先缓存的原因是提高性能。所以快速回答是:减少缓存。
现在可能有一些方法可以修改您的缓存方案,以便它使用更少的主内存并避免颠簸。例如,您可能会发现缓存到文件或数据库而不是内存可以提高性能。我发现文件系统和数据库缓存可以比应用程序缓存更有效,并且可以在多个实例之间共享。
另一个想法可能是更改算法以减少其他区域的内存使用量。例如,Perl程序不是将整个文件拉入内存,而是逐行更好地阅读。
最后,你有没有探究过the Memoize module?它可能不会立即适用,但它可能是一个想法的来源。
答案 6 :(得分:0)
我找不到办法做到这一点。
但是,我发现了(详见this)
分配给词汇的内存(即 my()变量)无法回收或 即使它们超出范围也会重复使用。 它保留在变量的情况下 回到范围。分配内存 全局变量可以重用 (在你的程序中)使用 undef()ing和/或delete()。
所以,我相信这里的一种可能性就是检查我是否可以在给定的时间点减少词汇变量的总内存打印。
答案 7 :(得分:0)
听起来您正在寻找 limit 或 ulimit 。但我怀疑这会导致超出限制的脚本失败,这可能不是你想要的。
更好的想法可能是在进程之间共享缓存数据。根据我的经验,将数据放入数据库或文件中效果很好。
我不想这么说,但如果你的内存限制如此严重,Perl可能不是这个应用程序的正确语言。我认为C是一个更好的选择。
答案 8 :(得分:0)
您可以做的一件事是使用solaris区域(容器) 您可以将您的进程放在一个区域中,并为其分配RAM和CPU等资源 以下是一些教程的两个链接:
答案 9 :(得分:0)
虽然它没有按照您的要求进行预分配,但您可能还需要查看大页面大小选项,这样当perl必须要求操作系统为您的程序提供更多内存时,它才能获得它 更大的块。
请参阅Solaris Internals: Multiple Page Size Support,了解有关此差异以及如何执行此操作的详细信息。