Ich bin mit einem Speicherfehler in meinem Code konfrontiert. Mein Parser kann so zusammenfassen:Freier Speicher während Schleife
# 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 to_json(self):
return json.dumps(self.to_dict())
def parse_file(file_path):
list_result = []
with open(file_path) as fin:
for line in fin:
parsed_line_obj = MyParserIter(line)
list_result.append(parsed_line_obj)
return list_result
def write_to_file(list_obj):
with open("out.out", "w") as fout:
for obj in list_obj:
json_out = obj.to_json()
fout.write(json_out + "\n")
obj.free_all()
obj = None
if __name__ == '__main__':
result_list = parse_file('test.in')
print(sys.getsizeof(result_list))
write_to_file(result_list)
print(sys.getsizeof(result_list))
# the same result for memory usage result_list
print(sys.getsizeof([None] * len(result_list)))
# the result is not the same :(
Ziel (große) Datei zu analysieren ist, jede Zeile in ein JSON-Objekt umgewandelt, das wieder in eine Datei geschrieben werden.
Mein Ziel ist es, den Footprint zu reduzieren, da dieser Code in einigen Fällen einen Speicherfehler auslöst. Nach jeder fout.write
möchte ich löschen (freier Speicher) obj
Referenz.
Ich habe versucht, obj
auf Keine der Methode obj.free_all()
aufrufen, aber keiner von ihnen den Speicher freigeben. Ich habe auch simplejson anstelle von json verwendet, die den Footprint reduziert haben, aber in einigen Fällen immer noch zu groß.
test.in sucht wie:
test1:OK,test3:OK,...
test1:OK,test3:OK,...
test1:OK,test3:OK,test4:test_again...
....
Haben Sie gc.collect() bereits versucht? Siehe: http://stackoverflow.com/questions/1316767/how-can-i-explicitly-free-memory-in-python – JonnyTieM
Wie groß ist Ihr test.in? – YOU
Für den echten Parser ist die Eingabedatei etwa 300 MB. –