в CPython свободен, потому что он возвращает адрес памяти x, который никогда не меняется. Но для Jython это сложно, потому что Java может перемещать объекты в памяти в любое время.

аюсь понять, как python использует память, чтобы оценить, сколько процессов я могу запустить одновременно. Сейчас я обрабатываю большие файлы на сервере с большим количеством оперативной памяти (~ 90-150 ГБ свободной оперативной памяти).

Для теста я бы сделал что-то на python, а затем посмотрел на htop, чтобы увидеть, как оно использовалось.

Шаг 1: Я открываю файл размером 2,55 ГБ и сохраняю его в строку

with open(file,'r') as f:
    data=f.read()

Использование 2686M

шаг 2: я разбил файл на новые строки

data = data.split('\n')

использование 7476M

шаг 3: я сохраняю только каждую четвертую строку (две из трех удаляемых строк имеют одинаковую длину с сохраняемой строкой)

data=[data[x] for x in range(0,len(data)) if x%4==1]

использование 8543M

Шаг 4: Я разделил это на 20 равных частей, чтобы пройти через многопроцессорный пул.

l=[] 
for b in range(0,len(data),len(data)/40):
    l.append(data[b:b+(len(data)/40)])

использование 8621M

шаг 5: я удаляю данные,использование 8496M.

Есть несколько вещей, которые не имеют смысла для меня.

На втором шаге, почему использование памяти увеличивается так сильно, когда я изменяю строку в массив. Я предполагаю, что контейнеры массива намного больше, чем контейнер строки?

на третьем шаге почему данные не сжимаются значительно. По сути, я избавился от 3/4 моих массивов и как минимум от 2/3 данных в массиве. Я ожидал бы, что это уменьшится соответственно. Вызов сборщика мусора не имел никакого значения.

как ни странно, когда я назначил меньший массив другой переменной, он использует меньше памяти.использование 6605M

когда я удаляю старый объектdata: использование 6059M

Это кажется странным для меня. Любая помощь по уменьшению моего следа памяти была бы признательна.

РЕДАКТИРОВАТЬ

Хорошо, это заставляет мою голову болеть. Очевидно, что Python делает некоторые странные вещи за кулисами здесь ... и только Python. Я сделал следующий сценарий, чтобы продемонстрировать это, используя мой оригинальный метод и метод, предложенный в ответе ниже. Числа все в ГБ.

ТЕСТОВЫЙ КОД

import os,sys
import psutil
process = psutil.Process(os.getpid())
import time

py_usage=process.memory_info().vms / 1000000000.0
in_file = "14982X16.fastq"

def totalsize(o):
    size = 0
    for x in o:
        size += sys.getsizeof(x)
    size += sys.getsizeof(o)
    return "Object size:"+str(size/1000000000.0)

def getlines4(f):
    for i, line in enumerate(f):
        if i % 4 == 1:
            yield line.rstrip()

def method1():
    start=time.time()
    with open(in_file,'rb') as f:
        data = f.read().split("\n")
    data=[data[x] for x in xrange(0,len(data)) if x%4==1]
    return data

def method2():
    start=time.time()
    with open(in_file,'rb') as f:
        data2=list(getlines4(f))
    return data2


print "method1 == method2",method1()==method2()
print "Nothing in memory"
print "Usage:", (process.memory_info().vms / 1000000000.0) - py_usage
data=method1()
print "data from method1 is in memory"
print "method1", totalsize(data)
print "Usage:", (process.memory_info().vms / 1000000000.0) - py_usage
del data
print "Nothing in memory"
print "Usage:", (process.memory_info().vms / 1000000000.0) - py_usage
data2=method2()
print "data from method2 is in memory"
print "method2", totalsize(data2)
print "Usage:", (process.memory_info().vms / 1000000000.0) - py_usage
del data2
print "Nothing is in memory"
print "Usage:", (process.memory_info().vms / 1000000000.0) - py_usage


print "\nPrepare to have your mind blown even more!"
data=method1()
print "Data from method1 is in memory"
print "Usage:", (process.memory_info().vms / 1000000000.0) - py_usage
data2=method2()
print "Data from method1 and method 2 are in memory"
print "Usage:", (process.memory_info().vms / 1000000000.0) - py_usage
data==data2
print "Compared the two lists"
print "Usage:", (process.memory_info().vms / 1000000000.0) - py_usage
del data
print "Data from method2 is in memory"
print "Usage:", (process.memory_info().vms / 1000000000.0) - py_usage
del data2
print "Nothing is in memory"
print "Usage:", (process.memory_info().vms / 1000000000.0) - py_usage

ВЫХОД

method1 == method2 True
Nothing in memory
Usage: 0.001798144
data from method1 is in memory
method1 Object size:1.52604683
Usage: 4.552925184
Nothing in memory
Usage: 0.001798144
data from method2 is in memory
method2 Object size:1.534815518
Usage: 1.56932096
Nothing is in memory
Usage: 0.001798144

Prepare to have your mind blown even more!
Data from method1 is in memory
Usage: 4.552925184
Data from method1 and method 2 are in memory
Usage: 4.692287488
Compared the two lists
Usage: 4.692287488
Data from method2 is in memory
Usage: 4.56169472
Nothing is in memory
Usage: 0.001798144

для тех, кто использует python3, он довольно похож, за исключением того, что после операции сравнения все не так плохо ...

ВЫХОД ИЗ PYTHON3

method1 == method2 True
Nothing in memory
Usage: 0.004395008000000006
data from method1 is in memory
method1 Object size:1.718523294
Usage: 5.322555392
Nothing in memory
Usage: 0.004395008000000006
data from method2 is in memory
method2 Object size:1.727291982
Usage: 1.872596992
Nothing is in memory
Usage: 0.004395008000000006

Prepare to have your mind blown even more!
Data from method1 is in memory
Usage: 5.322555392
Data from method1 and method 2 are in memory
Usage: 5.461917696
Compared the two lists
Usage: 5.461917696
Data from method2 is in memory
Usage: 2.747633664
Nothing is in memory
Usage: 0.004395008000000006

Мораль этой истории ... память для python, похоже, похожа на Camelot для Monty Python ... это очень глупое место.

Ответы на вопрос(1)

Ваш ответ на вопрос