【问题标题】:How do you pre allocate memory to a process in solaris?如何在 solaris 中为进程预分配内存?
【发布时间】:2014-04-05 23:05:21
【问题描述】:

我的问题是:

我有一个使用大量内存的 perl 脚本(由于缓存的预期行为)。但是,我注意到我做的缓存越多,它变得越慢,并且进程大部分时间都处于睡眠模式。

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

这里有人有什么想法吗?

更新

我想我在这里不是很清楚。我会更清楚地提出问题:

我不是在寻找在 perl 脚本中进行预分配的方法。我认为这对我没有多大帮助。我感兴趣的是一种告诉操作系统为我的 perl 脚本分配 X 内存量的方法,这样它就不必与稍后进入的其他进程竞争。

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

【问题讨论】:

  • 这会使您的流程变慢。通过强制次优内存使用,其他进程将需要更多 I/O,从而使您的进程变慢。

标签: unix memory solaris


【解决方案1】:

我从您的帖子和 cmets 中收集到的是:

  • 当内存使用量增加时,您的程序会变慢
  • 您的程序越来越多地花时间睡觉,而不是计算。

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

如果确实如此,您的最佳选择是:

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

预分配内存无济于事。在任何一种情况下,内存需求都会在某个时候超过可用的主内存。然后内核必须决定哪些页面现在需要在内存中,哪些页面可以被清除并重新用于更迫切需要的页面。如果所有经常需要的页面(工作集)都超过了主内存的大小,则系统会不断地将页面从辅助存储(交换)移动到辅助存储(交换)。然后,系统被认为是颠簸,并没有花太多时间做有用的工作。除了增加内存或减少使用内存之外,您无能为力。

【讨论】:

  • 非常有帮助的答案。也许是迄今为止最好的。如果我能破解,我会尝试 vmstat 并在这里更新。我正在投票(对不起,我只能投票一次)
【解决方案2】:

来自评论:

内存限制不是很严重,但内存占用很容易增长到 GB,当我们有竞争内存的进程时,它会变得非常慢。我想从操作系统中保留一些内存,这样即使有太多其他进程来了,抖动也很小。贾格马尔

那么让我们采取不同的策略。问题并不在于您的 Perl 脚本。相反,机器上的所有进程都消耗了太多内存,机器无法按照配置进行处理。

您可以“保留”内存,但这并不能防止抖动。事实上,这可能会使问题变得更糟,因为操作系统不会知道您是在使用内存还是只是将其保存以备后用。

我怀疑你正在受苦the tragedy of the commons。我对很多其他用户在有问题的机器上是对的吗?如果是这样,这更像是一个社会问题而不是技术问题。您需要有人(可能是系统管理员)介入并协调机器上的所有进程。他们应该找到最奢侈的内存消耗者,并与他们的程序员一起减少系统资源的成本。此外,他们应该安排要调度的进程,以便资源分配是有效的。最后,他们可能需要获得更多或改进的硬件来处理预期的系统负载。

【讨论】:

  • 这确实很有帮助。我赞成它(我希望我能投票不止一次)。
【解决方案3】:

您可能会问自己一些问题:

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

【讨论】:

  • 现在,答案是肯定的,是的,不是的。我会尽快扔掉不必要的东西。为了清楚起见,我已经相应地更新了问题。
【解决方案4】:
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)

不熟悉您的代码,我会在这里冒险一些疯狂的猜测 [咧嘴笑] 这些技术不会为您的脚本提供新的高效率,但预分配可能会有所帮助。

祝你好运!

-- 道格拉斯·亨特

【讨论】:

    【解决方案5】:

    我最近重新发现了一个出色的Randal L. Schwartz article,其中包括预分配数组。假设这是您的问题,您可以使用该代码的变体来测试预分配。但一定要测试结果。

    更多缓存导致脚本变慢的原因可能是thrashing。大概缓存的原因首先是为了提高性能。所以一个快速的答案是:减少缓存。

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

    另一个想法可能是更改您的算法以减少其他区域的内存使用量。例如,与其将整个文件拉入内存,Perl 程序往往会更好地逐行读取。

    最后,你探索过the Memoize module吗?它可能不会立即适用,但它可能是想法的来源。

    【讨论】:

      【解决方案6】:

      我还没有找到方法。

      但是,我发现了(详见this

      分配给词汇的内存(即 my() 变量)无法回收或 即使超出范围,也可以重用。 它被保留以防变量 回到范围。分配的内存 to 全局变量可以重用 (在您的程序中)通过使用 undef()ing 和/或 delete()。

      所以,我相信这里的一种可能性是检查我是否可以在给定的时间点减少词法变量的总内存打印。

      【讨论】:

        【解决方案7】:

        听起来您正在寻找 limitulimit。但我怀疑这会导致超出限制的脚本失败,这可能不是您想要的。

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

        我不想这么说,但是如果您的内存限制如此严重,那么 Perl 可能不适合此应用程序。我认为 C 会是更好的选择。

        【讨论】:

        • 内存限制不是很严重,但是内存占用很容易增长到 GB,当我们有竞争内存的进程时,它变得非常慢。我想从操作系统中保留一些内存,这样即使有太多其他进程来了,抖动也会最小化。
        【解决方案8】:

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

        1. Solaris Containers How To Guide
        2. Zone Resource Control in the Solaris 10 08/07 OS

        【讨论】:

          【解决方案9】:

          虽然它没有按照您的要求进行预分配,但您可能还想查看大页面大小选项,以便当 perl 必须向操作系统请求为您的程序提供更多内存时,它会进入 更大的块。

          请参阅Solaris Internals: Multiple Page Size Support 了解更多信息,了解这样做的不同之处以及如何做到这一点。

          【讨论】:

            【解决方案10】:

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

            您也可以内联一个 c 函数来执行上述操作。

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

            【讨论】:

              猜你喜欢
              • 2012-03-08
              • 2012-09-24
              • 1970-01-01
              • 1970-01-01
              • 2015-12-05
              • 2018-09-07
              • 1970-01-01
              • 2016-05-31
              • 2014-07-17
              相关资源
              最近更新 更多