我正在编写一个扭曲的PB应用程序,似乎使用了大量的内存,当用户断开连接时,它似乎永远不会被释放。
我有一个pb.Root对象,客户端连接并调用一个返回pb.Referenceable对象的远程方法,该对象在创建内存时将大量信息读入内存(大约2GB的数据)以加快速度行动。此对象以及有关客户端的其他一些信息将插入到列表中。
当客户端与服务器断开连接时,我会对此对象调用一些清理操作,以删除对正在存储的缓存对象的引用。 chunkCache是我存储数据的字典。
def disconnected(self):
self.connected = False
self.chunkCache = None
self.cur.close()
一旦客户端根据顶部永不丢弃而断开内存使用量,它仍会显示2Gb。
我是否应该担心这个问题,或者分配的内存是否会在需要时释放,或者如果没有任何想法我怎么能释放这个内存?它是在创建对象时创建的,不会在其他任何地方传递。
在该对象中我有一个deferToThread调用,这可能会停止正在释放的项目吗?
我在Linux上使用python 2.7。
更新:
我很困惑,我刚刚在我的对象中添加了自定义__del__
方法并在其中放置了一个print语句并且它们正在被删除,那么为什么内存使用量永远不会下降呢?
由于
迪安
答案 0 :(得分:2)
在大多数当前的操作系统中,动态内存的分配发生在通常称为堆的地方(不要与同名的数据结构混淆),这实际上只是一个从某个基地址开始并扩展的连续区域到基地址加上当前堆的大小。进程从小堆开始 - 通常只有几页 - 并且通过以系统页面大小的正整数倍为单位向上扩展段来增长。在该空间内,分配/解除分配创建较小的内存块以满足程序的需要,以及分配器跟踪分配内存和不分配内存所需的任何元数据。这些较小的内存块可能会随着时间的推移而被释放,使得堆段基本上是空的,但除非它是专门编码的,否则堆段很少会缩小。因此,长时间运行的进程往往会出现一个与其峰值使用量一样大的堆段。如果需要为其他进程释放物理内存,那么正在使用但不再使用的页面将倾向于移交交换,但过程映像仍然看起来“大”,并且通常不会缩小没有重新启动。有很多方法可以使用其他内存分配机制(例如,为临时文件映射内存空间并在完成时取消映射并删除它),但程序需要专门编码才能这样做。用C或C ++编写的使用标准库分配例程(分别为malloc
/ free
或new
/ delete
)的应用程序,包括Python编译器/解释器,将倾向于表现出上述行为。