当前位置: 首页 > 面试题库 >

如何使用子进程强制python释放内存?

李鸿
2023-03-14
问题内容

我正在阅读Python内存管理,希望减少应用程序的内存占用。有人建议,子流程可以大大减轻该问题;但是我在概念上需要做些麻烦。可以请一个简单的例子说明如何解决这个问题。

def my_function():
    x = range(1000000)
    y = copy.deepcopy(x)
    del x
    return y

@subprocess_witchcraft
def my_function_dispatcher(*args):
    return my_function()

…变成一个 真正的 子处理函数,该函数不存储额外的“自由列表”?

奖励问题:

这个“自由列表”概念也适用于python c扩展吗?


问题答案:

关于优化建议的重要事项是确保my_function()仅在子流程中调用该建议。该deepcopydel是无关的-
一旦你在过程中创造500万个不同的整数,抓着他们都在同一时间,它的比赛结束了。即使您停止引用这些对象,Python也会通过在静态状态下保留对500万个空整数对象大小的字段的引用来释放它们,以等待它们重用于下一个要创建500万个整数的函数。这是
免费清单
在另一个答案中提到,它购买了int和float的快速分配和释放。对于Python来说公平的是,这并不是内存泄漏,因为内存肯定可以用于进一步的分配。但是,该内存将在处理结束之前不会返回给系统,也不会重用于分配相同类型的数字。


大多数程序都不会出现此问题,因为大多数程序不会创建病理上庞大的数字列表,不会释放它们,然后期望将该内存重新用于其他对象。使用程序numpy也是安全的,因为numpy以紧密包装的本机格式存储其数组的数字数据。对于确实遵循这种使用模式的程序,减轻问题的方法是首先不要同时创建大量整数,至少不需要在需要将内存返回给系统的过程中创建大量整数。目前尚不清楚您拥有的确切用例,但实际解决方案可能需要的不仅仅是“魔术装饰器”。

这是子进程进入的地方:如果数字列表是在另一个进程中创建的,那么与该列表关联的所有内存(包括但不限于int的存储)都可以通过终止操作而被释放并返回给系统。子流程。当然,您必须设计程序,以便可以在子系统中创建和处理列表,而无需传输所有这些数字。子流程可以接收创建数据集所需的信息,并且可以将通过处理列表获得的信息发回。

为了说明原理,让我们升级示例,以便实际上需要存在整个列表-
假设我们正在对排序算法进行基准测试。我们要创建一个庞大的整数列表,对其进行排序,并可靠地释放与该列表关联的内存,以便下一个基准测试可以根据自己的需求分配内存,而不必担心RAM不足。要生成子流程并进行通信,将使用以下multiprocessing模块:

# To run this, save it to a file that looks like a valid Python module, e.g.
# "foo.py" - multiprocessing requires being able to import the main module.
# Then run it with "python foo.py".

import multiprocessing, random, sys, os, time

def create_list(size):
    # utility function for clarity - runs in subprocess
    maxint = sys.maxint
    randrange = random.randrange
    return [randrange(maxint) for i in xrange(size)]

def run_test(state):
    # this function is run in a separate process
    size = state['list_size']
    print 'creating a list with %d random elements - this can take a while... ' % size,
    sys.stdout.flush()
    lst = create_list(size)
    print 'done'
    t0 = time.time()
    lst.sort()
    t1 = time.time()
    state['time'] = t1 - t0

if __name__ == '__main__':
    manager = multiprocessing.Manager()
    state = manager.dict(list_size=5*1000*1000)  # shared state
    p = multiprocessing.Process(target=run_test, args=(state,))
    p.start()
    p.join()
    print 'time to sort: %.3f' % state['time']
    print 'my PID is %d, sleeping for a minute...' % os.getpid()
    time.sleep(60)
    # at this point you can inspect the running process to see that it
    # does not consume excess memory

奖励答案

由于红利问题不清楚,因此很难提供答案。“自由列表概念”正是一个概念,一种实现策略,需要在常规Python分配器之上显式编码。大多数Python类型 都不
使用该分配策略,例如,该class语句不用于使用该语句创建的类的实例。实施免费名单并不难,但是它相当先进,很少出于没有正当理由而进行。如果某个扩展作者
选择使用免费列表作为其类型之一,可以预期他们知道免费列表提供的折衷方案-
以一些额外的空间为代价获得超快的分配/重新分配(对于免费列表中的对象)以及空闲列表本身),并且无法将内存用于其他用途。



 类似资料:
  • 我改进了代码,以便从垃圾收集器中获得更好的结果。 现在,当我调用时,它确实释放了所有内存。但是,当我在不调用 的情况下观察内存使用情况时,应用程序确实会保留并使用越来越多的内存。 这是否意味着我的改进正在起作用,我的所有引用都是正确的,我可以忽略JVM是如何自己释放内存的。或者,我的代码中是否存在其他问题,这些问题是JVM在不运行垃圾收集器的情况下保留更多内存的原因。

  • 问题内容: 我在具有16GB Ram和64位OS的Linux机器上运行Python 2.7。我编写的python脚本可能会将过多的数据加载到内存中,这使计算机的运行速度降低到我什至无法杀死进程的地步。 虽然可以通过以下方式限制内存: 在运行脚本之前,请在外壳程序中添加一个限制选项。在我到处看的地方,该模块具有与相同的功能。但是调用: 在我的脚本开始时,绝对没有任何作用。即使将值设置为12000,也

  • 问题内容: 是否有一个静态分析工具可以在IDE外部运行一致地强制使用@Override注释?CheckStyle具有MissingOverride检查,但仅适用于使用@inheritDoc Javadoc标记的方法。我正在寻找一种可以在连续集成计算机上的新构建配置中运行的工具。 问题答案: 一种方法是使用TeamCity的“检查”运行器。我不确定它是否真的可以在IDE之外运行,因为它是在Intel

  • 问题内容: 我尝试为使用Python 3.x编写的项目创建文档。Sphinx是我要使用 的 工具,根据官方网站的说法,其最新版本1.1.2与Python 3.1+ 兼容。我的操作系统是Archlinux,这是一个使用Python 3.2+作为默认Python软件包的Linux发行版。 安装和配置非常简单(然后),从来没有要求我在2.x或3.x Python解释器之间进行选择。但是,当我要求Sphi

  • 本文向大家介绍Shell实现强制释放内存脚本分享,包括了Shell实现强制释放内存脚本分享的使用技巧和注意事项,需要的朋友参考一下 公司服务器最近两天老是因为内存被使用满而造成死机,实在是受不了老叫机房的人去帮忙重启,专门写了个脚本来释放下内存,当然这台服务器不是太重要,我粗鲁的处理方式估计不会适合大多数服务器,请大家使用之前先考虑清楚,不然造成数据丢失就不关我的事了. 脚本内容: cat che

  • 问题内容: 如果一个类定义了一个注释,是否有可能迫使其子类定义相同的注释? 例如,我们有一个简单的类/子类对,它们共享 我想做的事情,就是迫使每个进一步的子类定义相同的注释,以防止将来出现问题。 TestClass.java: TestSubClass.java: 我知道我可以在运行时枚举所有批注并检查是否丢失了,但是我真的很想在编译时执行此操作(如果可能)。 问题答案: 您可以在编译时使用JSR