ABC causing massive memory swell

Đang mở
#94,284 3 bình luận 1 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức phù hợp với người mới
25/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
python
Lĩnh vực
compilers

Hướng nghiên cứu

Bắt đầu bằng cách chạy reproducer được cung cấp trên các phiên bản Python bị ảnh hưởng và đo bộ nhớ trong vòng lặp issubclass. Đọc hành vi liên quan của ABCMeta và issubclass, sau đó so sánh các phát hiện với các issue #92810 và pydantic #3829. Được xem là hoàn tất khi một phương án đã được thống nhất và kiểm thử giải quyết việc cache tăng trưởng và việc duyệt cây lớp con mà không làm hồi quy hành vi đăng ký ABC.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

3.12 performance stdlib type-bug

Bug report

from abc import ABC, ABCMeta
from datetime import datetime


abcclasses = set()

normalclasses = set()

for i in range(10000):
    abcclasses.add(ABCMeta("abc_"+str(i), (ABC, ), {}))
    normalclasses.add(type("normal_"+str(i), (object,), {}))


if __name__ == '__main__':

    starttime = datetime.now()
    import os, psutil
    process = psutil.Process(os.getpid())
    mb = 1024 * 1024
    mem = last = process.memory_info().rss
    print(f'{i + 1:>4d} {mem / mb:8.2f}MB {(mem - last) / mb:+8.2f}MB | {"━" * int(mem / 8_000_000)}')
    for item in normalclasses:
        issubclass(item, ABC)

    mem = process.memory_info().rss
    print(f'{i + 1:>4d} {mem / mb:8.2f}MB {(mem - last) / mb:+8.2f}MB | {"━" * int(mem / 8_000_000)}')
    print(f"This took {datetime.now()-starttime}")

Your environment

Running this takes several minutes and consumes over 20 gbs of memory.

I've checked it against python 3.8-3.10. The issue is just that ABC caches every single issubclass evaluation combined with it searching its entire subclass tree recursively causes it to grind to a halt if you have any significant number of subclass 10k sub classes of ABC and 10k normal classes being compared to the base ABC climbs to over 20 GBs. I am not really sure it is necessary to check the entire subclass tree. I presume it is because of concerns about register calls happening low in the class tree.

It would likely be far more efficient to chase upward the calls to register and place those in the parent classes then to search the entire class hierarchy. This can get really aggressive performance issues if you have any multiple inheritance structures going on as well as those will get checked multiple times.

See these issues.
https://github.com/python/cpython/issues/92810
https://github.com/samuelcolvin/pydantic/issues/3829

Ngôn ngữ chính
Python
Star
77.2k
Fork
36k
Merge trung bình
1 ngày 9 giờ
Pull request đã merge (30 ngày)
558

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của python/cpython

Tất cả issue của python/cpython

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.