这是我用来测试内存分配的代码
import pycurl
import io
url = "http://www.stackoverflow.com"
buf = io.BytesIO()
print(len(buf.getvalue())) #here i am getting 0 as length
c = pycurl.Curl()
c.setopt(c.URL, url)
c.setopt(c.CONNECTTIMEOUT, 10)
c.setopt(c.TIMEOUT, 10)
c.setopt(c.ENCODING, 'gzip')
c.setopt(c.FOLLOWLOCATION, True)
c.setopt(c.IPRESOLVE, c.IPRESOLVE_V4)
c.setopt(c.USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0) Gecko/20100101 Firefox/8.0')
c.setopt(c.WRITEFUNCTION, buf.write)
c.perform()
c.close()
print(len(buf.getvalue())) #here length of the dowloaded file
print(buf.getvalue())
buf.close()
如何通过BytesIO获取分配的缓冲区/内存长度? 我在这做错了什么? python不分配固定的缓冲区长度?
答案 0 :(得分:20)
我不确定分配的缓冲区/内存长度是什么意思,但是如果你想在BytesIO
对象中存储用户数据的长度,你可以做到
>>> bio = io.BytesIO()
>>> bio.getbuffer().nbytes
0
>>> bio.write(b'here is some data')
17
>>> bio.getbuffer().nbytes
17
但这似乎相当于您目前使用的len(buf.getvalue())
。
可以使用sys.getsizeof()
:
>>> bio = io.BytesIO()
>>> sys.getsizeof(bio)
104
或者你可能会讨厌并直接调用__sizeof__()
(类似于sys.getsizeof()
但没有适用于该对象的垃圾收集器开销):
>>> bio = io.BytesIO()
>>> bio.__sizeof__()
72
根据需要分配BytesIO
的内存,并进行一些缓冲:
>>> bio = io.BytesIO()
>>> for i in range(20):
... _=bio.write(b'a')
... print(bio.getbuffer().nbytes, sys.getsizeof(bio), bio.__sizeof__())
...
1 106 74
2 106 74
3 108 76
4 108 76
5 110 78
6 110 78
7 112 80
8 112 80
9 120 88
10 120 88
11 120 88
12 120 88
13 120 88
14 120 88
15 120 88
16 120 88
17 129 97
18 129 97
19 129 97
20 129 97
答案 1 :(得分:2)
io.BytesIO()
返回具有功能tell()
的标准文件对象。它报告当前描述符的位置,并且不会复制整个缓冲区来计算总大小,而以len(bio.getvalue())
中的bio.getbuffer().nbytes
表示。这是一种非常快速,简单的方法,可以获取缓冲区对象中已用内存的确切大小。
我发布了示例代码和更详细的答案here
答案 2 :(得分:0)
您还可以使用tracemalloc
通过将内存事件包装在tracemalloc.get_traced_memory()
中来获取有关对象大小的间接信息
请注意,程序的活动线程(如果有的话)和副作用会影响输出,但如果进行大量采样,也可能更能代表实际内存成本,如下所示。
>>> import tracemalloc
>>> from io import BytesIO
>>> tracemalloc.start()
>>>
>>> memory_traces = []
>>>
>>> with BytesIO() as bytes_fh:
... # returns (current memory usage, peak memory usage)
# ..but only since calling .start()
... memory_traces.append(tracemalloc.get_traced_memory())
... bytes_fh.write(b'a' * (1024**2)) # create 1MB of 'a'
... memory_traces.append(tracemalloc.get_traced_memory())
...
1048576
>>> print("used_memory = {}b".format(memory_traces[1][0] - memory_traces[0][0]))
used_memory = 1048870b
>>> 1048870 - 1024**2 # show small overhead
294