Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python程序消耗RAM_Python_Linux_Memory Management_Garbage Collection_Raspberry Pi - Fatal编程技术网

Python程序消耗RAM

Python程序消耗RAM,python,linux,memory-management,garbage-collection,raspberry-pi,Python,Linux,Memory Management,Garbage Collection,Raspberry Pi,我编写了一个小程序,使用MinimalModbus通过串行端口收集数据。数据被转储到CSV文件中。我在某地和其他地方读过几篇帖子。提到的几件事是: 尽可能使用延迟求值(xrange而不是range) 删除大型未使用对象 使用子进程,当它们死亡时,操作系统会释放内存 脚本在github上。我还使用了一个工具来定期将这些文件上传到服务器。 这两个脚本都相当简单。此外,系统上没有其他任何东西在运行,因此我觉得使用这两个系统只会占用内存。 解决这个问题的最好办法是什么。我不是最愿意采用子流程路线的 更多

我编写了一个小程序,使用MinimalModbus通过串行端口收集数据。数据被转储到CSV文件中。我在某地和其他地方读过几篇帖子。提到的几件事是:

  • 尽可能使用延迟求值(xrange而不是range)
  • 删除大型未使用对象
  • 使用子进程,当它们死亡时,操作系统会释放内存
  • 脚本在github上。我还使用了一个工具来定期将这些文件上传到服务器。 这两个脚本都相当简单。此外,系统上没有其他任何东西在运行,因此我觉得使用这两个系统只会占用内存。 解决这个问题的最好办法是什么。我不是最愿意采用子流程路线的

    更多信息:

  • 数据收集在Raspberry Pi(512 MB RAM)上
  • Python版本:2.7
  • RAM完全使用大约需要3-4天,之后树莓会结冰
  • 我按照指南找到了消耗RAM的前20个程序

    $ ps aux | awk '{print $2, $4, $11}' | sort -k2rn | head -n 20
    12434 2.2 python
    12338 1.2 python
    2578 0.8 /usr/sbin/console-kit-daemon
    30259 0.7 sshd:
    30283 0.7 -bash
    1772 0.6 /usr/sbin/rsyslogd
    2645 0.6 /usr/lib/policykit-1/polkitd
    2146 0.5 dhclient
    1911 0.4 /usr/sbin/ntpd
    12337 0.3 sudo
    12433 0.3 sudo
    1981 0.3 sudo
    30280 0.3 sshd:
    154 0.2 udevd
    16994 0.2 /usr/sbin/sshd
    17006 0.2 ps
    1875 0.2 /usr/bin/dbus-daemon
    278 0.2 udevd
    290 0.2 udevd
    1 0.1 init
    
    因此,这两个Python进程占用了一些RAM,但与总体RAM消耗相比,这是非常小的。下面是free命令的输出

    pi@raspberrypi ~ $ free -m
                 total       used       free     shared    buffers     cached
    Mem:           438        414         23          0         45        320
    -/+ buffers/cache:         48        389
    Swap:           99          0         99
    
    以下是top命令的输出

    Tasks:  69 total,   1 running,  68 sleeping,   0 stopped,   0 zombie
    %Cpu(s): 66.9 us,  5.0 sy,  0.0 ni, 18.1 id,  0.0 wa,  0.0 hi, 10.0 si,  0.0 st
    KiB Mem:    448776 total,   429160 used,    19616 free,    47016 buffers
    KiB Swap:   102396 total,        0 used,   102396 free,   332288 cached
    
    PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND           
    12338 root    20   0 10156 5644 2384 S  69.8  1.3   3059:31 python            
    26039 root    20   0     0    0    0 S   1.6  0.0   0:02.71 kworker/0:1       
    26863 pi      20   0  4664 1356 1028 R   1.3  0.3   0:00.12 top               
    1982 root     20   0  1752  516  448 S   0.3  0.1   1:08.36 sh                
    1985 root     20   0  1692  552  460 S   0.3  0.1   5:15.16 startpar          
    1 root        20   0  2144  728  620 S   0.0  0.2   0:17.43 init              
    2 root        20   0     0    0    0 S   0.0  0.0   0:00.14 kthreadd          
    3 root        20   0     0    0    0 S   0.0  0.0   0:13.20 ksoftirqd/0       
    5 root         0 -20     0    0    0 S   0.0  0.0   0:00.00 kworker/0:0H      
    7 root         0 -20     0    0    0 S   0.0  0.0   0:00.00 kworker/u:0H      
    8 root         0 -20     0    0    0 S   0.0  0.0   0:00.00 khelper           
    9 root        20   0     0    0    0 S   0.0  0.0   0:00.00 kdevtmpfs         
    10 root       0 -20     0    0    0 S   0.0  0.0   0:00.00 netns             
    12 root      20   0     0    0    0 S   0.0  0.0   0:00.06 bdi-default       
    13 root       0 -20     0    0    0 S   0.0  0.0   0:00.00 kblockd 
    
    编辑2

    正如第一个答案中所建议的,我决定查看日志文件。我看了一下syslog,下面是tail对它的研究结果

    May 19 10:03:26 raspberrypi wpa_supplicant[7065]: wlan0: Failed to initialize driver    interface
    May 19 10:03:49 raspberrypi wpa_supplicant[7157]: nl80211: 'nl80211' generic netlink not found
    May 19 10:03:49 raspberrypi wpa_supplicant[7157]: Failed to initialize driver 'nl80211'
    May 19 10:03:49 raspberrypi wpa_supplicant[7157]: rfkill: Cannot open RFKILL control device
    May 19 10:03:49 raspberrypi wpa_supplicant[7157]: Could not read interface wlan0 flags: No such device
    
    这些消息正在填充日志文件,并且每秒都会出现。有趣的是,我使用的是以太网而不是WiFi


    因此,现在还不清楚RAM到哪里去了?

    大多数RAM对应用程序是免费的,因为它用于缓冲区和缓存。查看“-/+buffers/cache:”行以查看实际使用/空闲的RAM数量。可以找到一个解释

    要验证Python是否正在泄漏内存,请随时间监视Python的RSS大小(或%mem)。例如,编写一个shell脚本,每隔几个小时从cron作业调用一次,将
    ps
    命令链的输出和
    free
    命令的输出附加到文件中

    如果您发现Python进程正在泄漏内存,那么您可以做几件事

    • 修改脚本,使其在24小时后运行,并使用cron作业等重新启动脚本(简单的解决方法)
    • 深入了解Python本身,特别是您正在使用的扩展模块。使用该模块监控并影响内存使用情况。例如,您可以定期调用
      gc.count()
      ,以监视标记为收集的对象的数量。您可以显式调用
      gc.collect()
      ,看看这是否减少了内存使用。您还可以修改集合阈值
    如果Python的RAM使用不随时间增加,它可能是另一个守护进程程序。我上面提到的内存日志脚本应该告诉您它是哪一个

    还有一个原因可能是你的电脑冻结了。查看Linux日志文件以获取线索

    编辑:既然您已经填写了日志文件,您应该检查文件系统的状态。完整的文件系统可能会导致系统挂起。如果您没有使用无线接口,请禁用它

    import gc
    gc.collect()
    

    为我工作。这是罗兰·史密斯(Roland Smith)的公认答案,我认为未来的搜索者指出它作为答案是有用的。

    可能太晚了,但我在droplet ubuntu服务器上遇到了同样的问题。有一个cron作业,每15分钟运行一次python脚本。三天后,我的记忆耗尽了。所以我决定每x分钟通过cron-beas杀死一次python,因为我没有找到解决方案

    我用了这个:

    pkill-f scriptName.py


    这是一个合理的解释。但为什么它会随着时间的推移而不断增加呢。我怎样才能确定它不会导致系统冻结(3-4天内发生)?@NipunBatra你必须仔细观察系统。请参阅更新的答案。谢谢,我们已开始深入查看日志。添加编辑2以突出显示可能与问题相关的有趣内容。还可以编写脚本,以便在建议时使用包管理器从系统中删除wpa_请求者。