[Python] RSS Memory and Virtual Memory do not decrease even after killing a playwright...

Discussão em 'Python' iniciado por Stack, Abril 24, 2025.

  1. Stack

    Stack Membro Participativo

    I'm doing continuous iteration tests with playwright on a website and I noticed that RSS Memory and Virtual Memory are gradually increasing and no direct method is managing to dissipate the memory consumption. I've already tried every 100 iterations:

    1. Refresh the current page to avoid generating memory waste accumulation (didn't work)
    2. Continue work in a new tab and close the previous one that had memory waste accumulation (didn't work)
    3. Destroy the current instance of playwright and start a completely new one (didn't work)

    I've tested it for a few hours and it's becoming unfeasible because there comes a point where it consumes so much memory that it becomes impossible to run on a server.
    ​

    The current test I did by destroying playwright and starting a completely new one:

    from playwright.sync_api import sync_playwright
    from urllib.parse import urlparse
    import time
    import psutil
    import os
    from threading import Thread

    def create_proxy(proxy_string:str) -> Dict[str, str]:
    try:
    proxy_ip, proxy_port, proxy_user, proxy_pass = proxy_string.split(":")
    proxies = {
    "http": f"http://{proxy_user}:{proxy_pass}@{proxy_ip}:{proxy_port}",
    "https": f"http://{proxy_user}:{proxy_pass}@{proxy_ip}:{proxy_port}",
    }
    return proxies
    except ValueError:
    raise ValueError("Invalid Proxy format. Expected: IP:port:user:password")

    class PlaywrightBrowser:
    def __init__(self, proxy_string):
    self.proxies = create_proxy(proxy_string)
    proxy_url = self.proxies['http']
    parsed = urlparse(proxy_url)
    self.server = f"{parsed.scheme}://{parsed.hostname}:{parsed.port}"
    self.username = parsed.username
    self.password = parsed.password
    self.playwright = sync_playwright().start()
    self.browser = self.playwright.chromium.launch(
    proxy={
    "server": self.server,
    "username": self.username,
    "password": self.password
    }
    )
    self.context = self.browser.new_context()

    def new_page(self):
    return self.context.new_page()

    def close(self):
    if self.context:
    self.context.close()
    if self.browser:
    self.browser.close()
    if self.playwright:
    self.playwright.stop()

    def setup_page(page, url):
    page.goto(url, timeout=60000)
    page.wait_for_selector("#result", timeout=30000)

    def monitor_dice(proxy_string, url):
    try:
    pb = PlaywrightBrowser(proxy_string)
    page = pb.new_page()
    setup_page(page, url)

    print("Monitoring dice result. Press Ctrl+C to stop.")
    iteration_count = 0

    while True:
    page.wait_for_function("document.querySelector('#result').textContent.length > 0", timeout=15000)
    result = page.query_selector("#result").text_content().strip()
    print(f"Dice result: {result}")

    iteration_count += 1
    if iteration_count % 100 == 0:
    print("Restarting Playwright to free memory...")
    page.close()
    pb.close()
    pb = PlaywrightBrowser(proxy_string)
    page = pb.new_page()
    setup_page(page, url)

    time.sleep(1)

    except KeyboardInterrupt:
    print("\nMonitoring interrupted by user.")
    except Exception as e:
    print(f"Error: {e}")
    raise
    finally:
    if 'pb' in locals():
    pb.close()
    print("Execution finished.")

    def monitor_resources():
    process = psutil.Process(os.getpid())
    while True:
    cpu_percent = process.cpu_percent(interval=1)
    memory_info = process.memory_info()
    memory_rss = memory_info.rss / 1024 / 1024 # Memory in MB
    memory_vms = memory_info.vms / 1024 / 1024 # Virtual memory in MB
    print(f"CPU: {cpu_percent}% | RSS Memory: {memory_rss:.2f} MB | Virtual Memory: {memory_vms:.2f} MB")
    time.sleep(1)

    if __name__ == "__main__":
    monitor_thread = Thread(target=monitor_resources, daemon=True)
    monitor_thread.start()
    proxy_string = "111.222.33.44:55555:AAAAAAAA:BBBBBBBB" # Replace with your proxy
    url = "http://olympus.realpython.org/dice"
    monitor_dice(proxy_string, url)

    Continue reading...

Compartilhe esta Página