如何释放Python占用的内存
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何释放Python占用的内存相关的知识,希望对你有一定的参考价值。
1.充分利用内存任何一种图像处理软件对内存的要求都很高,Photoshop也一样。如果你在使用Photoshop时,没有使用其它的一些大软件,这时你就可以将Photoshop占用内存资源的比例提高。方法是:进行Photoshop,选择菜单下File\Preference\Memory & Image Cache命令,将Used by Photoshop的比例提高到80%~90%即可。
2.指定虚拟内存
在处理Photoshop时,内存被用完是很正常的,到时会大大影响Photoshop处理图像的时间,哪将怎么解决呢?方法是:你可以用硬盘来作为内存来使用,也就是常说的虚拟内存。请选择菜单下“File\Preference\Plug-Ins & Scratch Disks”命令。在这里的Scratch Disks下,你可以在硬盘上指定四个驱动器来作为虚拟内存,软件默认的虚拟内存是在Windows\temp之下。当第一个虚拟内存被使用光之后,Photoshop会自动去使用第二个Scratch Dsik,这样就提高了执行速度。
3.释放内存与硬盘空间
在进行图像处理时,你所进行的所有操作将会记录在Photoshop的History(历史记录)工作板中。这些操作包括:复制到Clipboard(粘贴板)、Undo(恢复)、Pattern(填充物)、Histories(记录)等几种,选择菜单下“Edit\Purge”命令。
进行这些操作之后,Photoshop会将这些图像和数据保存在内存里,使用该命令后,即将这些被占用的内存空间释放出来(RAM:Oh! Freeden)这样就让Photoshop有更多的Resource(资源)可用,自然就提高了效率。但注意,如果这些操作占用的内存比较少时,就没有必要使用啦!
除此之外,在处理大型图片时,Photoshop会自动产生一些临时文件,一般都很大,如果你处理的是一个20MB大小的宣传画时,那么临时文件可能就是100~150MB。请在Windows\temp或在你设定虚拟内存的驱动器里,将产生的Photoshop临时文件*.tmp删除掉。 参考技术A python内存一把不需要手工去释放
1、python中有自动回收垃圾的机制
2、大部分变量使用结束后,系统自动回收,不需要手工
3、程序结束后,自动释放,不需要做处理!
Python 字典内存释放及其浅拷贝和深拷贝之间的区别
背景
在用Python搭建服务过程使用字典存放自定义的对象,需要特别指出的是value值是占用内存空间较大的对象。随着时间的流逝和数据的累积,字典的key变得越来越多,从而使得整个字典对象占用过大的内存空间。此时,需要根据实际需要定期删除特定的keys,及时释放内存,否则就可能引发血案:OOM,进程被kill。
字典内存释放
众所周知,去掉字典中元素可以使用 pop 或者 del 方法,但是这两种方法都没有真正地释放对应的元素的空间。Python 为了保证hash table 探测链的完整,对于那个被删除的key只是被标记成了空,并没有真正被删除掉,所以该字典的内存占用没有得到释放。这是为了避免多度重建hash table。那么,如何真正释放这部分内存空间呢?可以创建或者拷贝一个旧字典再覆盖掉新字典。具体示例如下:
import sys
import gc
import copy
a =
print("init empty dict memory size= bytes".format(sys.getsizeof(a)))
for i in range(10**6):
a[i] = i
print("after set value, dict memory size= bytes".format(sys.getsizeof(a)))
for i in range(10**6):
del a[i]
# a.pop(i)
print("after del, dict memory size= bytes".format(sys.getsizeof(a)))
a_new = dict(a)
print("after init a new one, dict memory size= bytes".format(sys.getsizeof(a_new)))
b = copy.copy(a)
print("after copy a new one, dict memory size= bytes".format(sys.getsizeof(b)))
c = copy.deepcopy(a)
print("after deepcopy a new one, dict memory size= bytes".format(sys.getsizeof(c)))
运行结果如下:
init empty dict memory size=240 bytes
after set value, dict memory size=41943144 bytes
after del, dict memory size=41943144 bytes
after init a new one, dict memory size=240 bytes
after copy a new one, dict memory size=240 bytes
after deepcopy a new one, dict memory size=240 bytes
笔者在实验过程中还发现一个有趣的问题:字典调用 clear 操作后的内存占用比新建一个字典的内存占用小。具体示例如下:
dict =
print(sys.getsizeof(dict)) # 240, 这因为新的字典的 size 是 PyDict_MINSIZE
dict.clear()
print(sys.getsizeof(dict)) # 72
这是因为新建字典是按照PyDict_MINSIZE
分配keyspace。当调用.clear()
函数后,keyspace 被重新分配到一个静态的空keyspace: Py_EMPTY_KEYS,此时的字典是真的empty。
上述示例代码中使用浅拷贝和深拷贝的方式释放空间,那么这里进一步介绍下直接赋值、浅拷贝和深拷贝之间的区别。
浅拷贝 Vs 深拷贝
简而言之:
-
直接赋值:其实就是对象的引用(别名)。
-
浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。
-
深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。
浅拷贝
浅拷贝的示例代码如下:
class test_obj:
def __init__(self, obj_id, text, label='0'):
self.obj_id = obj_id
self.text = text
self.label = label
ob1 = test_obj("id1", "文本1", 'label1')
a = "k1": "12345", "k2": [0, 1, 2], "k3": ob1
b = a.copy() # 浅拷贝
print("b=", b)
a["k2"].append(4) # 由于是浅拷贝,所以key所引用的对象是相同的,所以会造成b的值也随a变化
print("Append a")
print("a=", a)
print("b=", b)
# 如果是 pop 掉key的话
print("Pop b:")
b.pop("k2")
# a.pop("k2")
print("a=", a)
print("b=", b)
# 修改值
print("Modify object value:")
print("values of a=", vars(a["k3"]))
b["k3"].text = "换文本了"
print("values of a=", vars(a["k3"]))
运行结果如下:
b= 'k1': '12345', 'k2': [0, 1, 2], 'k3': <__main__.test_obj object at 0x7f1aa09e8f60>
Append a
a= 'k1': '12345', 'k2': [0, 1, 2, 4], 'k3': <__main__.test_obj object at 0x7f1aa09e8f60>
b= 'k1': '12345', 'k2': [0, 1, 2, 4], 'k3': <__main__.test_obj object at 0x7f1aa09e8f60>
Pop b:
a= 'k1': '12345', 'k2': [0, 1, 2, 4], 'k3': <__main__.test_obj object at 0x7f1aa09e8f60>
b= 'k1': '12345', 'k3': <__main__.test_obj object at 0x7f1aa09e8f60>
Modify object value:
values of a= 'obj_id': 'id1', 'text': '文本1', 'label': 'label1'
values of a= 'obj_id': 'id1', 'text': '换文本了', 'label': 'label1'
浅拷贝下,a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象(即为引用)。所以,子对象的值改变的话,两者都会改变;而 pop 或者 del 特定key,则由于是独立对象不会相互影响。所以当需要在程序中动态地删除某些key(特别是key所对应的value占用较大内存空间),且要释放内存空间的话可以使用浅拷贝的方式重新赋值,否则单纯 pop 特定key并不会释放字典的内存空间。
深拷贝
深拷贝, a 和 b 完全拷贝了父对象及其子对象,两者是完全独立的。
深拷贝的示例代码:
import copy
class test_obj:
def __init__(self, obj_id, text, label='0'):
self.obj_id = obj_id
self.text = text
self.label = label
ob1 = test_obj("id1", "文本1", 'label1')
a = "k1": "12345", "k2": [0, 1, 2], "k3": ob1
b = copy.deepcopy(a)
print("a=", a)
print("b=", b)
a["k2"].append(4)
print("Append a")
print("a=", a)
print("b=", b)
# 如果是 pop 掉key的话
print("Pop b:")
b.pop("k2")
# a.pop("k2")
print("a=", a)
print("b=", b)
# 修改值
print("Modify object value:")
b["k3"].text = "换文本了"
print("values of a=", vars(a["k3"]))
print("values of b=", vars(b["k3"]))
运行结果如下:
a= 'k1': '12345', 'k2': [0, 1, 2], 'k3': <__main__.test_obj object at 0x7fbf660cdf98>
b= 'k1': '12345', 'k2': [0, 1, 2], 'k3': <__main__.test_obj object at 0x7fbf660d30b8>
Append a
a= 'k1': '12345', 'k2': [0, 1, 2, 4], 'k3': <__main__.test_obj object at 0x7fbf660cdf98>
b= 'k1': '12345', 'k2': [0, 1, 2], 'k3': <__main__.test_obj object at 0x7fbf660d30b8>
Pop b:
a= 'k1': '12345', 'k2': [0, 1, 2, 4], 'k3': <__main__.test_obj object at 0x7fbf660cdf98>
b= 'k1': '12345', 'k3': <__main__.test_obj object at 0x7fbf660d30b8>
Modify object value:
values of a= 'obj_id': 'id1', 'text': '文本1', 'label': 'label1'
values of b= 'obj_id': 'id1', 'text': '换文本了', 'label': 'label1'
以上是关于如何释放Python占用的内存的主要内容,如果未能解决你的问题,请参考以下文章