我们如何为solaris中的进程预分配内存?

时间:2020-03-06 14:40:09  来源:igfitidea点击:

我的问题是:

我有一个使用大量内存的Perl脚本(由于缓存,行为异常)。但是,我注意到我做的缓存越多,获取的速度就越慢,并且该过程大部分时间都花在睡眠模式上。

我认为为该进程预分配内存可能会提高性能。

有人在这里有什么想法吗?

更新:

我想我在这里不是很清楚。我将以更清楚的方式提出问题:

我不是在perl脚本中寻找预分配的方法。我认为这不会对我有太大帮助。我感兴趣的是一种告诉OS为我的perl脚本分配X内存量的方法,这样它就不必与以后的其他进程竞争。

假设我无法摆脱内存使用问题。虽然,我也在探索减少这种情况的方法,但是不要期望在那里有太大的改进。
仅供参考,我正在使用solaris 10机器。

解决方案

我们可能会问自己一些问题:

  • 我的数据结构对手头的任务真的有用吗?
  • 我真的必须缓存那么多吗?
  • 一段时间后可以丢弃高速缓存的数据吗?

看看http://metacpan.org/pod/Devel::Size

我们也可以内联c函数来执行上述操作。

据我所知,我们不能直接从Perl分配内存。我们可以通过编写XS模块或者使用内联的C函数(如我所提到的)来解决此问题。

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)

不熟悉代码,我在这里冒昧地猜测[笑]这些技术不会为脚本提供新的巨大效率,但是预分配可以有所帮助。

祝你好运!

-道格拉斯·亨特(Douglas Hunter)

我最近重新发现了Randal L. Schwartz的精彩文章,其中包括预分配数组。假设这是问题,则可以使用该代码的变体来测试预分配。但是请务必测试结果。

脚本随着更多的缓存而变慢的原因可能是崩溃的。大概首先要缓存的原因是为了提高性能。因此,一个快速的答案是:减少缓存。

现在,可能存在一些方法来修改缓存方案,以便它使用较少的主内存并避免崩溃。例如,我们可能会发现缓存到文件或者数据库而不是缓存可以提高性能。我发现文件系统和数据库缓存比应用程序缓存更有效,并且可以在多个实例之间共享。

另一个想法可能是更改算法以减少其他区域的内存使用量。例如,Perl程序不是将整个文件拉入内存,而是倾向于逐行读取效果更好。

最后,我们是否探索了"记忆"模块?它可能不会立即适用,但可能是想法的来源。

我还没有找到一种方法来做到这一点。

但是,我发现了这一点(有关详细信息,请参阅此内容)

Memory allocated to lexicals (i.e.
  my() variables) cannot be reclaimed or
  reused even if they go out of scope.
  It is reserved in case the variables
  come back into scope. Memory allocated
  to global variables can be reused
  (within your program) by using
  undef()ing and/or delete().

因此,我相信这里的可能性可能是检查我是否可以减少给定时间点的词汇变量的总内存打印量。

听起来我们正在寻找限制或者ulimit。但是我怀疑这将导致超出限制的脚本失败,这可能不是我们想要的。

一个更好的主意可能是在进程之间共享缓存的数据。根据我的经验,将数据放入数据库或者文件中效果很好。

我不想这么说,但是如果内存限制如此严格,Perl可能不是此应用程序的正确语言。我认为C是一个更好的选择。

来自评论:

The memory limitations are not very severe but the memory footprint easily grows to GBs and when we have competing processes for memory, it gets very slow. I want to reserve some memory from OS so that thrashing is minimal even when too many other processes come. Jagmal

那我们就另辟tack径了。特别是Perl脚本并不是真正的问题。取而代之的是,计算机上的所有进程都消耗过多的内存,因此计算机无法按配置处理。

我们可以"保留"内存,但这不会阻止崩溃。实际上,这可能会使问题变得更糟,因为操作系统将不知道我们是在使用内存还是只是将其保存以备后用。

我怀疑我们正在遭受公地的悲剧。我对许多其他用户正在使用该机器是否正确?如果是这样,这更多的是社会问题,而不是技术问题。我们需要的是某个人(可能是系统管理员)介入并协调计算机上的所有进程。他们应该找到最浪费的内存,并与他们的程序员一起工作,以减少系统资源的成本。此外,他们应该安排流程的安排,以便资源分配有效。最后,他们可能需要获得更多或者改进的硬件来处理预期的系统负载。

我从帖子和评论中收集到的是:

  • 当内存使用量增加时,程序会变慢
  • 图表越来越多地花费时间在睡眠上,而不是在计算上。

最有可能的计划:睡眠意味着等待资源可用。在这种情况下,资源很可能是内存。使用vmstat 1命令进行验证。看看sr栏。如果持续超过〜150,系统将迫切希望释放页面以满足需求。在pi,po和fr列中伴随着高活性。

如果确实如此,那么我们最好的选择是:

  • 升级系统内存以满足需求
  • 将内存使用量降低到适合当前系统的水平。

预先分配内存将无济于事。无论哪种情况,内存需求在某个时候都会超出可用的主内存。然后,内核将必须决定现在哪些页面需要保存在内存中,以及哪些页面可能会被清除并重新用于更迫切需要的页面。如果所有常规需要的页面(工作集)都超出了主内存的大小,则系统会不断地在辅助存储(交换)之间移动页面。据说该系统正在运转,并花费大量时间进行有用的工作。除了增加内存或者减少使用内存之外,我们无能为力。

我们可以做的一件事是使用solaris区域(容器)。
我们可以将进程放在一个区域中并为其分配资源,例如RAM和CPU。
这是一些教程的两个链接:

  • Solaris容器指南
  • Solaris 10 08/07 OS中的区域资源控制

虽然它没有按照要求进行预分配,但我们可能还需要查看较大的页面大小选项,以便当perl必须要求OS为程序提供更多内存时,它才能将其放入
大块

有关这带来的差异以及如何执行的信息,请参见《 Solaris Internals:Multiple Page Size Support》。