netcdf4-python:随着从 netcdf 对象多次调用切片数据,内存增加

Posted

技术标签:

【中文标题】netcdf4-python:随着从 netcdf 对象多次调用切片数据,内存增加【英文标题】:netcdf4-python: memory increasing with numerous calls to slice data from netcdf object 【发布时间】:2013-10-19 06:16:46 【问题描述】:

我正在尝试使用 netcdf4-python 从 netcdf4 文件中读取数据切片。这是第一次使用 python,我遇到了内存问题。下面是代码的简化版本。在循环的每次迭代中,内存都会跳转相当于我读取的数据片。遍历每个变量时如何清理内存?

#!/usr/bin/env python
from netCDF4 import Dataset
import os
import sys
import psutil

process = psutil.Process(os.getpid())


def print_memory_usage():
    nr_mbytes = process.get_memory_info()[0] / 1048576.0
    sys.stdout.write("\n".format(nr_mbytes))
    sys.stdout.flush()

# open input file and gather variable info

rootgrp_i = Dataset('data.nc','r')
vargrp_i = rootgrp_i.variables
# lets create a dictionary to store the metadata in
subdomain = 
for suff in range(1000):

    for var in vargrp_i:
        v_i = vargrp_i[var]
        if v_i.ndim == 1:
           a=v_i[:]
        elif v_i.ndim == 2:
           a=v_i[0:20, 0:20]
        elif v_i.ndim == 3:
           a=v_i[0, 0:20, 0:20]
        elif v_i.ndim == 4:
           a=v_i[0, 0:75, 0:20, 0:20]
        else:
           a=v_i[0]
        del a
        print_memory_usage()

rootgrp_i.close()

【问题讨论】:

@user308827 你能在你看到内存泄漏的地方发布一些代码和/或版本信息吗?在使用 Python 2.7.6、netcdf4 1.1.9 和 psutil 3.1.1 的类似示例中,我无法看到泄漏。可以通过命令pip freeze获取模块版本信息。 你确定每次外循环的内存使用都会增加,而不仅仅是内循环的每次迭代? 你试过 gc - 垃圾收集器接口 (docs.python.org/2/library/gc.html) 吗? 有趣的是,我在 Windows 上没有看到这个问题。只是 Mac 操作系统 你能添加一个数据集来测试它吗? 【参考方案1】:

我认为问题在于对del a 含义的误解。

根据Python Language Reference:

删除名称会从本地或全局命名空间中删除该名称的绑定,具体取决于该名称是否出现在同一代码块的全局语句中。

这意味着del a 取消引用a 变量,但这并不意味着内存会立即释放,这取决于垃圾收集器的工作方式。您可以使用 collect() 方法让垃圾收集器收集新的垃圾:

import gc
gc.collect()

This 相关帖子很有用。

【讨论】:

感谢@SimoV8,我仍然很好奇为什么我只在 mac 而不是 windowss 上看到内存问题 我不能肯定,但我认为是由于垃圾收集器的不同实现。

以上是关于netcdf4-python:随着从 netcdf 对象多次调用切片数据,内存增加的主要内容,如果未能解决你的问题,请参考以下文章

从 netCDF 更快地读取时间序列?

Python3.7 函数从 netCDF4 的时间步长绘制日期时间

如何从 R 中的 netCDF 文件中提取变量名?

通过python从netCDF中提取数据

如何使用 R 中的纬度/经度边界从 netCDF 文件中获取子集

从 NetCDF 中提取数据