Jupyter笔记本电脑内存管理

时间:2020-02-27 11:22:03

标签: python numpy jupyter-notebook ipython jupyter

我目前正在kaggle中从事Jupyter笔记本的研究。在numpy数组上执行所需的转换后,我对其进行了腌制,以便可以将其存储在磁盘上。我这样做的原因是为了释放大型阵列消耗的内存。

腌制阵列后消耗的内存约为8.7 gb。

我决定运行@ jan-glx here提供的代码段,以找出哪些变量正在占用我的内存:

import sys

def sizeof_fmt(num, suffix='B'):
    ''' by Fred Cirera,  https://stackoverflow.com/a/1094933/1870254, modified'''
    for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
        if abs(num) < 1024.0:
            return "%3.1f %s%s" % (num, unit, suffix)
        num /= 1024.0
    return "%.1f %s%s" % (num, 'Yi', suffix)

for name, size in sorted(((name, sys.getsizeof(value)) for name, value in locals().items()),
                         key= lambda x: -x[1])[:10]:
    print("{:>30}: {:>8}".format(name, sizeof_fmt(size)))

执行完此步骤后,我注意到我的数组的大小为3.3 gb,所有其他变量的总和约为0.1 gb。

我决定通过执行以下操作删除该数组,并查看是否可以解决该问题:

del my_array
gc.collect()

这样做之后,内存消耗从8.7 gb减少到5.4 gb。从理论上讲这是有意义的,但仍然没有解释剩余的内存被消耗了什么。

无论如何,我决定继续并重置所有变量,以查看是否可以通过以下方式释放内存:

%reset

如预期的那样,它释放了上面函数中打印出的变量的内存,而我仍然剩下5.3 gb的正在使用的内存。

要注意的一件事是,我在腌制文件本身时注意到内存高峰,因此该过程的摘要如下:

  1. 对阵列执行的操作->内存消耗从大约1.9 gb增加到5.6 gb
  2. 腌制文件->内存消耗从5.6 gb增加到大约8.7 gb
  3. 当文件被酸洗到15.2 gb时,内存突然增加,然后又下降到8.7 gb。
  4. 已删除数组->内存消耗从8.7 gb减少到5.4 gb
  5. 执行重置->内存消耗从5.4 gb降低至5.3 gb

请注意,以上内容是基于监视kaggle上的内存的宽松方式,可能不准确。 我还检查了此question,但对我的情况没有帮助。

这将被视为内存泄漏吗?如果是这样,在这种情况下我该怎么办?

编辑1:

进一步研究之后,我发现有others面临此问题。此问题源于酸洗过程,酸洗会在内存中创建一个副本,但由于某种原因不会释放它。酸洗过程完成后,是否可以释放内存。

编辑2:

从磁盘删除腌制的文件时,使用:

!rm my_array 

它最终释放了磁盘空间,还释放了内存空间。我不知道上面的提示是否有用,但我还是决定将其包括在内,因为每一点信息都可能有所帮助。

1 个答案:

答案 0 :(得分:1)

您应该意识到一个基本的缺点:CPython解释器实际上是can actually barely free memory and return it to the OS。对于大多数工作负载,您可以假定在解释程序的生命周期中没有释放内存。但是,解释器可以在内部重新使用内存。因此,从操作系统的角度来看CPython进程的内存消耗确实没有任何帮助。一个相当普遍的解决方法是在子进程/工作进程(例如,通过multiprocessing)中运行占用大量内存的作业,然后“仅”将结果返回给主进程。工人死后,实际上释放了内存。

第二,在 <pre> <code> HTML code goes here. </code> </pre> 上使用 @objc func sectionHeaderTapped(_ recognizer: UITapGestureRecognizer) { headerView.removeFromSuperview() ... } 可能会令人产生误解。请改用sys.getsizeof属性,请注意,在处理views时,这也可能会产生误导。

此外,我不完全确定为什么要“刺破” numpy数组。有更好的工具来完成这项工作。仅举两个例子:h5py(基于HDF5的经典作品)和zarr。这两个库都允许您直接在磁盘上(和压缩)使用类似ndarray的对象-基本上消除了酸洗步骤。此外,zarr还允许您create compressed ndarray-compatible data structures in memory。来自numpy,scipy和朋友的ndarray.nbytes人必须愉快地接受它们作为输入参数。