我写了一个Python程序,它作用于一个大的输入文件,创建了几百万个表示三角形的对象.算法是:
在打印三角形之前打印出完整的顶点列表的OFF的要求意味着在将输出写入文件之前我必须在内存中保存三角形列表.与此同时,由于列表的大小,我遇到了内存错误.
告诉Python我不再需要某些数据的最佳方法是什么,它可以被释放?
我有一个非常大的csv文件,我在熊猫中打开如下....
import pandas
df = pandas.read_csv('large_txt_file.txt')
Run Code Online (Sandbox Code Playgroud)
一旦我这样做,我的内存使用量增加2GB,这是预期的,因为该文件包含数百万行.当我需要释放这个内存时,我的问题出现了.我跑了....
del df
Run Code Online (Sandbox Code Playgroud)
但是,我的内存使用率没有下降.这是释放熊猫数据帧所使用的内存的错误方法吗?如果是,那么正确的方法是什么?
我正在使用psycopg2(我升级到2.5版)在我的postgres数据库的python脚本中运行一个大型查询.查询完成后,我关闭光标和连接,甚至运行gc,但进程仍然消耗大量内存(确切地说是7.3gb).我错过了一个清理步骤吗?
import psycopg2
conn = psycopg2.connect("dbname='dbname' user='user' host='host'")
cursor = conn.cursor()
cursor.execute("""large query""")
rows = cursor.fetchall()
del rows
cursor.close()
conn.close()
import gc
gc.collect()
Run Code Online (Sandbox Code Playgroud) 我试图迭代超过100,000个图像并捕获一些图像功能,并将所得的dataFrame作为pickle文件存储在磁盘上。
不幸的是,由于RAM的限制,我被迫将图像分成20,000个大块并对其进行操作,然后再将结果保存到磁盘上。
在开始循环以处理下一个20,000图像之前,下面编写的代码应该保存20,000图像的结果数据框。
但是-这似乎没有解决我的问题,因为在第一个for循环结束时内存没有从RAM中释放
因此,在处理第50,000条记录时,该程序由于内存不足错误而崩溃。
在将对象保存到磁盘并调用垃圾收集器后,我尝试删除这些对象,但是RAM使用率似乎并未下降。
我想念什么?
#file_list_1 contains 100,000 images
file_list_chunks = list(divide_chunks(file_list_1,20000))
for count,f in enumerate(file_list_chunks):
# make the Pool of workers
pool = ThreadPool(64)
results = pool.map(get_image_features,f)
# close the pool and wait for the work to finish
list_a, list_b = zip(*results)
df = pd.DataFrame({'filename':list_a,'image_features':list_b})
df.to_pickle("PATH_TO_FILE"+str(count)+".pickle")
del list_a
del list_b
del df
gc.collect()
pool.close()
pool.join()
print("pool closed")
Run Code Online (Sandbox Code Playgroud) 我的代码中遇到内存错误.我的解析器可以总结如下:
# coding=utf-8
#! /usr/bin/env python
import sys
import json
from collections import defaultdict
class MyParserIter(object):
def _parse_line(self, line):
for couple in line.split(","):
key, value = couple.split(':')[0], couple.split(':')[1]
self.__hash[key].append(value)
def __init__(self, line):
# not the real parsing just a example to parse each
# line to a dict-like obj
self.__hash = defaultdict(list)
self._parse_line(line)
def __iter__(self):
return iter(self.__hash.values())
def to_dict(self):
return self.__hash
def __getitem__(self, item):
return self.__hash[item]
def free(self, item):
self.__hash[item] = None
def free_all(self):
for k in self.__hash:
self.free(k)
def …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用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, …
Run Code Online (Sandbox Code Playgroud) 我有以下最小的工作示例:
from pyspark import SparkContext
from pyspark.sql import SQLContext
import numpy as np
sc = SparkContext()
sqlContext = SQLContext(sc)
# Create dummy pySpark DataFrame with 1e5 rows and 16 partitions
df = sqlContext.range(0, int(1e5), numPartitions=16)
def toy_example(rdd):
# Read in pySpark DataFrame partition
data = list(rdd)
# Generate random data using Numpy
rand_data = np.random.random(int(1e7))
# Apply the `int` function to each element of `rand_data`
for i in range(len(rand_data)):
e = rand_data[i]
int(e)
# Return a single `0` value
return …
Run Code Online (Sandbox Code Playgroud) 我正在开发一个 Python 脚本,该脚本查询多个不同的数据库以整理数据并将所述数据保存到另一个数据库。该脚本从大约 15 个不同数据库的数百万条记录中收集数据。为了尝试加速脚本,我包含了一些缓存功能,归结为拥有一个包含一些经常查询的数据的字典。字典保存键值对,其中键是根据数据库名称、集合名称和查询条件生成的哈希值,值是从数据库中检索到的数据。例如:
{123456789: {_id: '1', someField: 'someValue'}}
哪里123456789
是散列,{_id: '1', someField: 'someValue'}
是从数据库中检索到的数据。
将这些数据保存在本地字典中意味着不必每次都查询数据库(这可能很慢),我可以在本地访问一些经常查询的数据。如前所述,有很多查询,因此字典可能会变得非常大(几 GB)。我有一些代码psutil
用于查看运行脚本的机器上有多少内存可用,如果可用内存低于某个阈值,我会清除字典。清除字典的代码是:
cached_documents.clear()
cached_documents = None
gc.collect()
cached_documents = {}
Run Code Online (Sandbox Code Playgroud)
我应该指出这cached_documents
是一个局部变量,它被传递到所有访问或添加到缓存的方法中。不幸的是,这似乎还不足以正确释放内存,因为即使在调用了上述代码之后,Python 仍然占用大量额外内存。您可以在此处查看内存使用情况:
值得注意的是,字典被清除的前几次,我们向系统释放了大量内存,但随后的每次似乎都更少,此时内存使用量趋于平缓,因为缓存被非常频繁地清除,因为自从可用内存在阈值内,因为 Python 占用了大量内存。
有没有办法在清除字典时强制 Python 正确释放内存,以避免平铺?任何提示表示赞赏。
我有类似于此的代码:
def memoryIntensiveFunction(x):
largeTempVariable = Intermediate(x)
processFunction(largeTempVariable,x)
Run Code Online (Sandbox Code Playgroud)
问题在于,temp
在我的测试用例中,该变量类似于 500 mb,但该空间在memoryIntensiveFunction
完成后不会返回给操作系统。我知道这是因为使用该guppy
工具进行的内存分析说largeTempVariable
已释放(即,在 Python 中),但psutil
表明它不是。我想我看到了这里描述的效果。问题是这个过程运行时间很长(即几个小时),memoryIntensiveFunction
在开始时运行并且永远不会再次运行,所以我不得不携带 500mb 几个小时很不方便。
我在这里和这里找到的一个解决方案建议使用单独的过程。多处理会产生自己的成本,但就我而言,这是值得的。但是,这需要重构memoryIntensiveFunction
调用者以接收x
返回值,而不是看到它就地修改。真正的杀手是我的对象x
不可选择(它大量使用了 boost python 扩展)。使可x
腌制的工作量很大。
有没有我没有考虑的选项?
我有一个python脚本,刮了一些网址.我有一个网址列表,每个网址我得到HTML并用它做一些逻辑.
我使用Python 2.7.6和Linux Mint 17 Cinnamon 64位.
问题是我的主要抓取对象(我为每个url实例化)从不从内存中释放,尽管没有引用它.有了这个问题,我的记忆就会不断增长和快速增长(因为我的目标有时非常大 - 高达50MB).
简化代码看起来像这样:
def scrape_url(url):
"""
Simple helper method for scraping url
:param url: url for scraping
:return: some result
"""
scraper = Scraper(url) # instance main Scrape object
result = scraper.scrape() # scrape it
return result
## SCRIPT STARTS HERE
urls = get_urls() # fetch some list of urls
for url in urls:
print 'MEMORY USAGE BEFORE SCRAPE: %s (kb)' % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
result = scrape_url(url) # call helper method for …
Run Code Online (Sandbox Code Playgroud) python ×10
memory ×4
memory-leaks ×3
pandas ×2
apache-spark ×1
dictionary ×1
json ×1
netcdf ×1
numpy ×1
optimization ×1
performance ×1
postgresql ×1
psutil ×1
psycopg2 ×1
pyspark ×1
python-2.7 ×1