<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>xixiwelcome (陈少寻欢)</title>
    <link>https://ruby-china.org/xixiwelcome</link>
    <description>fighting!</description>
    <language>en-us</language>
    <item>
      <title>Rails Server 与 Apache 的比较</title>
      <description>&lt;p&gt;Rails 本身能作为 Server，为什么部署的时候还需要 Apache 等 webserver 并需要安装 passenger 等。&lt;/p&gt;

&lt;p&gt;Rails Server 的哪些不足 使得他必须配合一个 websever。&lt;/p&gt;

&lt;p&gt;还有为什么 Rails 与 Apache 配合的时候 需要 passenger。&lt;/p&gt;

&lt;p&gt;这些概念搞的很模糊。&lt;/p&gt;</description>
      <author>xixiwelcome</author>
      <pubDate>Mon, 22 Jun 2015 17:36:14 +0800</pubDate>
      <link>https://ruby-china.org/topics/26131</link>
      <guid>https://ruby-china.org/topics/26131</guid>
    </item>
    <item>
      <title>如何阻止 Ruby 吃掉所有内存？（已解决）</title>
      <description>&lt;p&gt;问题已经解决，找来找去原来是一个用了很多年的工具类中有内存泄漏的问题。
这个类是一个单例，其中有一个很大的成员变量，如果使用完以后不及时清空，就会占用很多内存。 
因为之前跑了很多年，所以一直没有去怀疑这个公共类，这一次数据量暴增才暴露了问题。
严格来说也不能算内存泄漏，只是&lt;code&gt;GC.start&lt;/code&gt;是清理不掉依然被引用的内存的。&lt;/p&gt;

&lt;p&gt;同时，使用产生巨大无比的变量本身就存在问题，但谁也没有去改动他的想法。
上级给出的指示是，改动已经跑了很多年的文件（人工 + 风险），还不如等到出了问题花点钱买点内存了。
也许这就是许多公司的诟病吧，自己人轻言微，而且也确实不知道怎么解决这类问题（也许头儿是对的）。&lt;/p&gt;

&lt;p&gt;所以，目前只是将那个大大的变量使用过以后清空了，其他的就什么都没有做了。&lt;/p&gt;

&lt;p&gt;总结起来两点：
&lt;strong&gt;1. 不能过分相信已经跑了很久的东西，因为当年的工程师是否严谨你是不知道的&lt;/strong&gt;
&lt;strong&gt;2. 公司还是以利益至上&lt;/strong&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;&lt;strong&gt;原问题如下：&lt;/strong&gt;
近在做一个项目，内容很简单，就是读取数据文件，处理后存入数据库。环境：CentOS6.4，Ruby2.1
伪代码如下：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;arr_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;arr_data&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;deal_with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;#deal_with处理后返回一个字符串， 存入数组&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;arr_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
      &lt;span class="n"&gt;write_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;             &lt;span class="c1"&gt;#每1000行存一次文件，然后清空数组&lt;/span&gt;
      &lt;span class="n"&gt;arr_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;
      &lt;span class="c1"&gt;#GC.start&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;arr_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="n"&gt;write_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       
  &lt;span class="n"&gt;arr_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;
  &lt;span class="c1"&gt;#GC.start&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;
&lt;span class="no"&gt;GC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;
&lt;span class="c1"&gt;#`hostname`&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;是的，就是这样一个简单的任务（文件很大，有上亿行）， &lt;strong&gt;逐渐把服务器 32G 内存全都吃光了&lt;/strong&gt;。
但是，是可以顺利执行完毕的。&lt;/p&gt;

&lt;p&gt;问题出在，我在他执行完毕之后，需要发邮件报告结果。
发邮件的函数中 用到了 &lt;code&gt;hostname&lt;/code&gt; 这一系统命令。&lt;/p&gt;

&lt;p&gt;程序在此处 ERROR，  &lt;strong&gt;&lt;code&gt;Cannot allocate memory - hostname&lt;/code&gt;&lt;/strong&gt;。
也就是说，上面的那个循环已经全部执行完毕，但内存还是没有释放。&lt;/p&gt;

&lt;p&gt;尝试了许多做法，包括使用&lt;code&gt;GC.start&lt;/code&gt;，使用&lt;code&gt;WeakRef&lt;/code&gt;等。&lt;/p&gt;

&lt;p&gt;但是这些做法，均只是将内存回收给 Ruby 程序，并没有释放到操作系统。
所以最终还是会把系统内存吃光，导致最后无法执行&lt;code&gt;hostname&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;借此机会也把 Ruby 的内存管理，垃圾回收机制学习了一下，大致了解了其原理。
但是并没有见哪里提到 &lt;strong&gt;强制归还内存给操作系统&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;希望大神给点提示，解释一下 Ruby 为何疯狂的吃我的内存。
或者给出一些解决该问题的建议。&lt;/p&gt;

&lt;p&gt;万分感激~~&lt;/p&gt;</description>
      <author>xixiwelcome</author>
      <pubDate>Thu, 05 Mar 2015 14:29:37 +0800</pubDate>
      <link>https://ruby-china.org/topics/24475</link>
      <guid>https://ruby-china.org/topics/24475</guid>
    </item>
  </channel>
</rss>
