📜  Python请求中的内存泄漏

📅  最后修改于: 2022-05-13 01:55:10.080000             🧑  作者: Mango

Python请求中的内存泄漏

当程序员忘记清除堆内存中分配的内存时,就会发生内存泄漏。这是一种资源泄漏或浪费。当应用程序中出现内存泄漏时,机器的内存会被填满并降低机器的性能。在构建大型可扩展应用程序时,这是一个严重的问题。

请求:请求库是Python 的一个组成部分,用于向指定的 URL 发出 HTTP 请求。无论是 REST API 还是 Web Scrapping,都必须学习请求才能进一步使用这些技术。当一个人向一个 URI 发出请求时,它会返回一个响应。 Python请求提供了用于管理请求和响应的内置功能。

Gc 模块:模块 gc 是一个Python内置模块,它提供了一个Python垃圾收集器的接口。它提供了启用收集器、禁用收集器、调整收集频率、调试选项等功能。

在 C 和 C++ 等低级语言中,程序员应该手动释放未使用的资源,即编写代码来管理资源。但是像Python、 Java这样的高级语言有一个自动内存管理器的概念,称为垃圾收集器。垃圾收集器管理应用程序的内存分配和释放。

下面列出了我们将使用的一些 gc 方法。



  • get_objects():此方法返回垃圾收集器跟踪的所有对象的列表,不包括返回的列表。
  • collect():此方法释放由收集器维护的列表中的非引用对象。一些未引用的对象由于其实现而不会立即自动释放。

我们将在请求中使用 get() 方法,它返回一个响应对象。当响应对象未被引用时,即删除它的内存应该立即释放,但由于它的实现,资源不会自动释放。这是它的统计信息泄漏内存。

识别内存泄漏:

方法:

  • 获取并存储由收集器跟踪(创建和活动)的对象数量。您可以使用 gc.get_objects() 获取被跟踪对象的列表,然后使用 len函数计算 no。的对象。
  • 调用调用 request.get() 方法的函数。
  • 打印响应状态码,以便我们确认对象已创建。
  • 然后返回函数。当函数返回时,应删除函数内创建的所有内容。
  • 获取当前跟踪的对象数量,并将阀门与泄漏对象的先前值进行比较。
  • 如果当前返回的对象计数更大,则存在内存泄漏。

下面是实现:

Python3
import requests
import gc
 
def call():
   
    # call the get with a url,here I used google.com
    # get method returns a response object
    response = requests.get('https://google.com')
     
    # print the status code of response
    print("Status code", response.status_code)
     
    # After the function is been returned,
    # the response object becomes non-referenced
    return
 
 
def main():
    print("No.of tracked objects before calling get method")
     
    # gc.get_objects() returns list objects been tracked
    # by the collector.
    # print the length of object list with len function.
    print(len( gc.get_objects() ) )
     
    # make a call to the function, that calls get method.
    call()
 
    print("No.of tracked objects after calling get method")
     
    # print the length of object list with len function.
    print(len( gc.get_objects() ) )
 
if __name__ == "__main__":
    main()


Python3
import requests
import gc
 
def call():
   
    # call the get with a url,here I used google.com
    # get method returns a response object
    response = requests.get('https://google.com')
     
    # print the status code of response
    print("Status code",response.status_code)
     
    # After the function is been returned,
    # the response object becomes non-referenced
    return
 
 
def main():
    print("No.of tracked objects before calling get method")
     
    # gc.get_objects() returns list objects been tracked
    # by the collector.
    # print the length of object list with len function.
    print(len( gc.get_objects() ) )
     
    # make a call to the function, that calls get method.
    call()
     
    # collect method immediately free the resource of
    # non-refrenced object.
    gc.collect()
 
    # print the length of object list with len
    # function after removing non-refrenced object.
    print("No.of tracked objects after removing non-refrenced objects")
    print(len( gc.get_objects() ) )
 
 
if __name__ == "__main__":
    main()


输出:



No.of tracked objects before calling get method
16071
Status code 200
No.of tracked objects after calling get method
16158

修复内存泄漏:

一个简单的解决方案是手动调用 gc.collect() 方法,该方法将立即释放资源。

方法:

  • 获取并存储由收集器跟踪(创建和活动)的对象数量。您可以使用 gc.get_objects() 获取被跟踪对象的列表,然后使用 len函数计算 no。的对象。
  • 调用调用 request.get() 方法的函数。
  • 打印响应状态码,以便我们确认对象已创建。
  • 然后返回函数。当函数返回时,应删除函数内创建的所有内容。
  • 调用垃圾收集器释放未使用的资源,即调用 gc.collect() 方法。
  • 获取当前跟踪的对象数量,现在由于清理未使用的资源,您可以注意到数量较少的对象。

下面是实现:

蟒蛇3

import requests
import gc
 
def call():
   
    # call the get with a url,here I used google.com
    # get method returns a response object
    response = requests.get('https://google.com')
     
    # print the status code of response
    print("Status code",response.status_code)
     
    # After the function is been returned,
    # the response object becomes non-referenced
    return
 
 
def main():
    print("No.of tracked objects before calling get method")
     
    # gc.get_objects() returns list objects been tracked
    # by the collector.
    # print the length of object list with len function.
    print(len( gc.get_objects() ) )
     
    # make a call to the function, that calls get method.
    call()
     
    # collect method immediately free the resource of
    # non-refrenced object.
    gc.collect()
 
    # print the length of object list with len
    # function after removing non-refrenced object.
    print("No.of tracked objects after removing non-refrenced objects")
    print(len( gc.get_objects() ) )
 
 
if __name__ == "__main__":
    main()

输出:

No.of tracked objects before calling get method
16071
Status code 200
No.of tracked objects after removing non-refrenced objects
15954