# `tracemalloc` — Trace memory allocations

Нове в версії 3.4.

Вихідний код: Lib/tracemalloc.py

Модуль tracemalloc — це інструмент налагодження для відстеження блоків пам’яті, виділених Python. Він надає таку інформацію:

- Зворотне відстеження місця розміщення об’єкта

- Статистика виділених блоків пам’яті на ім’я файлу та номер рядка: загальний розмір, кількість і середній розмір виділених блоків пам’яті

- Обчисліть різницю між двома знімками, щоб виявити витоки пам’яті

Для відстеження більшості блоків пам’яті, виділених Python, модуль слід запускати якомога раніше, встановивши змінну середовища `PYTHONTRACEMALLOC` на `1` або використовуючи `-X` `tracemalloc` параметр командного рядка. Функцію `tracemalloc.start()` можна викликати під час виконання, щоб розпочати відстеження розподілу пам’яті Python.

За замовчуванням трасування виділеного блоку пам’яті зберігає лише останній кадр (1 кадр). Щоб зберегти 25 кадрів під час запуску: установіть для змінної середовища `PYTHONTRACEMALLOC` значення `25` або скористайтеся параметром командного рядка `-X` `tracemalloc=25`.

## Приклади

### Покажіть 10 найкращих

Відобразити 10 файлів, які виділяють найбільше пам’яті:

    import tracemalloc

    tracemalloc.start()

    # ... run your application ...

    snapshot = tracemalloc.take_snapshot()
    top_stats = snapshot.statistics('lineno')

    print("[ Top 10 ]")
    for stat in top_stats[:10]:
        print(stat)

Приклад результату набору тестів Python:

    [ Top 10 ]
    <frozen importlib._bootstrap>:716: size=4855 KiB, count=39328, average=126 B
    <frozen importlib._bootstrap>:284: size=521 KiB, count=3199, average=167 B
    /usr/lib/python3.4/collections/__init__.py:368: size=244 KiB, count=2315, average=108 B
    /usr/lib/python3.4/unittest/case.py:381: size=185 KiB, count=779, average=243 B
    /usr/lib/python3.4/unittest/case.py:402: size=154 KiB, count=378, average=416 B
    /usr/lib/python3.4/abc.py:133: size=88.7 KiB, count=347, average=262 B
    <frozen importlib._bootstrap>:1446: size=70.4 KiB, count=911, average=79 B
    <frozen importlib._bootstrap>:1454: size=52.0 KiB, count=25, average=2131 B
    <string>:5: size=49.7 KiB, count=148, average=344 B
    /usr/lib/python3.4/sysconfig.py:411: size=48.0 KiB, count=1, average=48.0 KiB

Ми бачимо, що Python завантажив дані `4855 KiB` (байт-код і константи) з модулів і що модуль `collections` виділив `244 KiB` для створення типів `namedtuple`.

Перегляньте `Snapshot.statistics()` для отримання додаткових параметрів.

### Обчислити відмінності

Зробіть два знімки та покажіть відмінності:

    import tracemalloc
    tracemalloc.start()
    # ... start your application ...

    snapshot1 = tracemalloc.take_snapshot()
    # ... call the function leaking memory ...
    snapshot2 = tracemalloc.take_snapshot()

    top_stats = snapshot2.compare_to(snapshot1, 'lineno')

    print("[ Top 10 differences ]")
    for stat in top_stats[:10]:
        print(stat)

Приклад результату до/після виконання деяких тестів набору тестів Python:

    [ Top 10 differences ]
    <frozen importlib._bootstrap>:716: size=8173 KiB (+4428 KiB), count=71332 (+39369), average=117 B
    /usr/lib/python3.4/linecache.py:127: size=940 KiB (+940 KiB), count=8106 (+8106), average=119 B
    /usr/lib/python3.4/unittest/case.py:571: size=298 KiB (+298 KiB), count=589 (+589), average=519 B
    <frozen importlib._bootstrap>:284: size=1005 KiB (+166 KiB), count=7423 (+1526), average=139 B
    /usr/lib/python3.4/mimetypes.py:217: size=112 KiB (+112 KiB), count=1334 (+1334), average=86 B
    /usr/lib/python3.4/http/server.py:848: size=96.0 KiB (+96.0 KiB), count=1 (+1), average=96.0 KiB
    /usr/lib/python3.4/inspect.py:1465: size=83.5 KiB (+83.5 KiB), count=109 (+109), average=784 B
    /usr/lib/python3.4/unittest/mock.py:491: size=77.7 KiB (+77.7 KiB), count=143 (+143), average=557 B
    /usr/lib/python3.4/urllib/parse.py:476: size=71.8 KiB (+71.8 KiB), count=969 (+969), average=76 B
    /usr/lib/python3.4/contextlib.py:38: size=67.2 KiB (+67.2 KiB), count=126 (+126), average=546 B

Ми бачимо, що Python завантажив `8173 KiB` даних модуля (байт-код і константи), і що це на `4428 KiB` більше, ніж було завантажено до тестів, коли було зроблено попередній знімок. Подібним чином модуль `linecache` кешував `940 КіБ` вихідного коду Python для форматування відстеження, усе це з попереднього знімка.

Якщо в системі мало вільної пам’яті, знімки можна записати на диск за допомогою методу `Snapshot.dump()` для аналізу знімка в автономному режимі. Потім скористайтеся методом `Snapshot.load()`, перезавантажте знімок.

### Отримати відстеження блоку пам’яті

Код для відображення зворотного відстеження найбільшого блоку пам’яті:

    import tracemalloc

    # Store 25 frames
    tracemalloc.start(25)

    # ... run your application ...

    snapshot = tracemalloc.take_snapshot()
    top_stats = snapshot.statistics('traceback')

    # pick the biggest memory block
    stat = top_stats[0]
    print("%s memory blocks: %.1f KiB" % (stat.count, stat.size / 1024))
    for line in stat.traceback.format():
        print(line)

Приклад результату набору тестів Python (зворотне відстеження обмежено 25 кадрами):

    903 memory blocks: 870.1 KiB
      File "<frozen importlib._bootstrap>", line 716
      File "<frozen importlib._bootstrap>", line 1036
      File "<frozen importlib._bootstrap>", line 934
      File "<frozen importlib._bootstrap>", line 1068
      File "<frozen importlib._bootstrap>", line 619
      File "<frozen importlib._bootstrap>", line 1581
      File "<frozen importlib._bootstrap>", line 1614
      File "/usr/lib/python3.4/doctest.py", line 101
        import pdb
      File "<frozen importlib._bootstrap>", line 284
      File "<frozen importlib._bootstrap>", line 938
      File "<frozen importlib._bootstrap>", line 1068
      File "<frozen importlib._bootstrap>", line 619
      File "<frozen importlib._bootstrap>", line 1581
      File "<frozen importlib._bootstrap>", line 1614
      File "/usr/lib/python3.4/test/support/__init__.py", line 1728
        import doctest
      File "/usr/lib/python3.4/test/test_pickletools.py", line 21
        support.run_doctest(pickletools)
      File "/usr/lib/python3.4/test/regrtest.py", line 1276
        test_runner()
      File "/usr/lib/python3.4/test/regrtest.py", line 976
        display_failure=not verbose)
      File "/usr/lib/python3.4/test/regrtest.py", line 761
        match_tests=ns.match_tests)
      File "/usr/lib/python3.4/test/regrtest.py", line 1563
        main()
      File "/usr/lib/python3.4/test/__main__.py", line 3
        regrtest.main_in_temp_cwd()
      File "/usr/lib/python3.4/runpy.py", line 73
        exec(code, run_globals)
      File "/usr/lib/python3.4/runpy.py", line 160
        "__main__", fname, loader, pkg_name)

Ми бачимо, що найбільше пам’яті було виділено в модулі `importlib` для завантаження даних (байт-код і константи) з модулів: `870.1 KiB`. Трасування – це місце, де `importlib` завантажував дані останнім часом: у рядку `import pdb` модуля `doctest`. Трасування може змінитися, якщо завантажується новий модуль.

### Досить топ

Код для відображення 10 рядків, які виділяють найбільшу кількість пам’яті, з гарним виведенням, ігноруючи файли `<frozen importlib._bootstrap>` і `<unknown>`:

    import linecache
    import os
    import tracemalloc

    def display_top(snapshot, key_type='lineno', limit=10):
        snapshot = snapshot.filter_traces((
            tracemalloc.Filter(False, "<frozen importlib._bootstrap>"),
            tracemalloc.Filter(False, "<unknown>"),
        ))
        top_stats = snapshot.statistics(key_type)

        print("Top %s lines" % limit)
        for index, stat in enumerate(top_stats[:limit], 1):
            frame = stat.traceback[0]
            print("#%s: %s:%s: %.1f KiB"
                  % (index, frame.filename, frame.lineno, stat.size / 1024))
            line = linecache.getline(frame.filename, frame.lineno).strip()
            if line:
                print('    %s' % line)

        other = top_stats[limit:]
        if other:
            size = sum(stat.size for stat in other)
            print("%s other: %.1f KiB" % (len(other), size / 1024))
        total = sum(stat.size for stat in top_stats)
        print("Total allocated size: %.1f KiB" % (total / 1024))

    tracemalloc.start()

    # ... run your application ...

    snapshot = tracemalloc.take_snapshot()
    display_top(snapshot)

Приклад результату набору тестів Python:

    Top 10 lines
    #1: Lib/base64.py:414: 419.8 KiB
        _b85chars2 = [(a + b) for a in _b85chars for b in _b85chars]
    #2: Lib/base64.py:306: 419.8 KiB
        _a85chars2 = [(a + b) for a in _a85chars for b in _a85chars]
    #3: collections/__init__.py:368: 293.6 KiB
        exec(class_definition, namespace)
    #4: Lib/abc.py:133: 115.2 KiB
        cls = super().__new__(mcls, name, bases, namespace)
    #5: unittest/case.py:574: 103.1 KiB
        testMethod()
    #6: Lib/linecache.py:127: 95.4 KiB
        lines = fp.readlines()
    #7: urllib/parse.py:476: 71.8 KiB
        for a in _hexdig for b in _hexdig}
    #8: <string>:5: 62.0 KiB
    #9: Lib/_weakrefset.py:37: 60.0 KiB
        self.data = set()
    #10: Lib/base64.py:142: 59.8 KiB
        _b32tab2 = [a + b for a in _b32tab for b in _b32tab]
    6220 other: 3602.8 KiB
    Total allocated size: 5303.1 KiB

Перегляньте `Snapshot.statistics()` для отримання додаткових параметрів.

#### Запис поточного та пікового розміру всіх відстежених блоків пам’яті

Наступний код неефективно обчислює дві суми, такі як `0 + 1 + 2 + ...`, створюючи список цих чисел. Цей список тимчасово займає багато пам’яті. Ми можемо використовувати `get_traced_memory()` і `reset_peak()`, щоб спостерігати за малим використанням пам’яті після обчислення суми, а також за максимальним використанням пам’яті під час обчислень:

    import tracemalloc

    tracemalloc.start()

    # Example code: compute a sum with a large temporary list
    large_sum = sum(list(range(100000)))

    first_size, first_peak = tracemalloc.get_traced_memory()

    tracemalloc.reset_peak()

    # Example code: compute a sum with a small temporary list
    small_sum = sum(list(range(1000)))

    second_size, second_peak = tracemalloc.get_traced_memory()

    print(f"{first_size=}, {first_peak=}")
    print(f"{second_size=}, {second_peak=}")

Вихід:

    first_size=664, first_peak=3592984
    second_size=804, second_peak=29704

Використання `reset_peak()` гарантувало, що ми можемо точно записати пік під час обчислення `small_sum`, навіть якщо він набагато менший, ніж загальний піковий розмір блоків пам’яті після виклику `start()`. Без виклику `reset_peak()`, `second_peak` все одно буде піком з обчислення `large_sum` (тобто рівним `first_peak`). У цьому випадку обидва піки значно перевищують остаточне використання пам’яті, і це означає, що ми могли б оптимізувати (вилучивши непотрібний виклик `list` і написавши `sum(range(...))` ).

## API

### Функції

tracemalloc.clear_traces()

  Очистити сліди блоків пам’яті, виділених Python.

  Дивіться також `stop()`.

tracemalloc.get_object_traceback(obj)

  Отримати зворотне відстеження, де було виділено об’єкт Python obj. Повертає екземпляр `Traceback` або `None`, якщо модуль `tracemalloc` не відстежує виділення пам’яті або не відстежує виділення об’єкта.

  Дивіться також функції `gc.get_referrers()` і `sys.getsizeof()`.

tracemalloc.get_traceback_limit()

  Отримайте максимальну кількість кадрів, що зберігаються в зворотній трасі.

  Модуль `tracemalloc` має відстежувати виділення пам’яті, щоб отримати обмеження, інакше виникає виняткова ситуація.

  Обмеження встановлюється функцією `start()`.

tracemalloc.get_traced_memory()

  Отримайте поточний розмір і максимальний розмір блоків пам’яті, які відстежуються модулем `tracemalloc`, як кортеж: `(current: int, peak: int)`.

tracemalloc.reset_peak()

  Установіть максимальний розмір блоків пам’яті, які відстежуються модулем `tracemalloc`, на поточний розмір.

  Нічого не робити, якщо модуль `tracemalloc` не відстежує виділення пам’яті.

  Ця функція лише змінює розмір записаного піку, але не змінює та не очищає жодні траси, на відміну від `clear_traces()`. Знімки, зроблені за допомогою `take_snapshot()` перед викликом `reset_peak()`, можна змістовно порівняти зі знімками, зробленими після виклику.

  Дивіться також `get_traced_memory()`.

  Нове в версії 3.9.

tracemalloc.get_tracemalloc_memory()

  Отримати дані про використання пам’яті в байтах модуля `tracemalloc`, який використовується для зберігання слідів блоків пам’яті. Повертає `int`.

tracemalloc.is_tracing()

  `True`, якщо модуль `tracemalloc` відстежує виділення пам’яті Python, `False` інакше.

  Дивіться також функції `start()` і `stop()`.

tracemalloc.start(nframe: int = 1)

  Почніть відстежувати виділення пам’яті Python: установіть перехоплювачі на розподільниках пам’яті Python. Зібрані зворотні трасування трасувань будуть обмежені кадрами nframe. За замовчуванням трасування блоку пам’яті зберігає лише останній кадр: обмеження становить `1`. nframe має бути більше або дорівнювати `1`.

  Ви все ще можете прочитати вихідну загальну кількість кадрів, які склали відстеження, переглянувши атрибут `Traceback.total_nframe`.

  Зберігання більш ніж 1 кадру корисне лише для обчислення статистики, згрупованої за `'traceback'` або для обчислення сукупної статистики: перегляньте методи `Snapshot.compare_to()` і `Snapshot.statistics()` .

  Зберігання більшої кількості кадрів збільшує навантаження на пам’ять і ЦП модуля `tracemalloc`. Використовуйте функцію `get_tracemalloc_memory()`, щоб виміряти, скільки пам’яті використовується модулем `tracemalloc`.

  Змінну середовища `PYTHONTRACEMALLOC` (`PYTHONTRACEMALLOC=NFRAME`) і параметр командного рядка `-X` `tracemalloc=NFRAME` можна використовувати для запуску трасування під час запуску.

  Дивіться також функції `stop()`, `is_tracing()` і `get_traceback_limit()`.

tracemalloc.stop()

  Зупиніть відстеження розподілу пам’яті Python: видаліть перехоплювачі розподільників пам’яті Python. Також очищає всі раніше зібрані сліди блоків пам’яті, виділених Python.

  Викличте функцію `take_snapshot()`, щоб зробити знімок слідів перед їх очищенням.

  Дивіться також функції `start()`, `is_tracing()` і `clear_traces()`.

tracemalloc.take_snapshot()

  Зробіть знімок слідів блоків пам’яті, виділених Python. Повернути новий екземпляр `Snapshot`.

  Знімок не включає блоки пам’яті, виділені до того, як модуль `tracemalloc` почав відстежувати виділення пам’яті.

  Відстеження трасування обмежено кадрами `get_traceback_limit()`. Щоб зберегти більше кадрів, використовуйте параметр nframe функції `start()`.

  Модуль `tracemalloc` повинен відстежувати виділення пам’яті, щоб зробити знімок, дивіться функцію `start()`.

  Дивіться також функцію `get_object_traceback()`.

### DomainFilter

class tracemalloc.DomainFilter(inclusive: bool, domain: int)

  Фільтрувати сліди блоків пам’яті за їх адресним простором (доменом).

  Нове в версії 3.6.

  inclusive

    Якщо inclusive має значення `True` (include), збігаються блоки пам’яті, виділені в адресному просторі `domain`.

    Якщо inclusive має значення `False` (виключити), збігаються блоки пам’яті, не виділені в адресному просторі `domain`.

  domain

    Адресний простір блоку пам’яті (`int`). Властивість лише для читання.

### фільтр

class tracemalloc.Filter(inclusive: bool, filename_pattern: str, lineno: int = None, all_frames: bool = False, domain: int = None)

  Фільтрувати сліди блоків пам’яті.

  Перегляньте функцію `fnmatch.fnmatch()`, щоб дізнатися про синтаксис шаблон_назви_файлу. Розширення файлу `'.pyc'` замінено на `'.py'`.

  приклади:

  - `Filter(True, subprocess.__file__)` містить лише сліди модуля `subprocess`

  - `Filter(False, tracemalloc.__file__)` виключає сліди модуля `tracemalloc`

  - `Filter(False, "<unknown>")` виключає порожні відстеження

  Змінено в версії 3.5: Розширення файлу `'.pyo'` більше не замінюється на `'.py'`.

  Змінено в версії 3.6: Додано атрибут `domain`.

  domain

    Адресний простір блоку пам’яті (`int` або `None`).

    tracemalloc використовує домен `0` для відстеження розподілу пам’яті, зробленого Python. Розширення C можуть використовувати інші домени для відстеження інших ресурсів.

  inclusive

    Якщо inclusive має значення `True` (include), збігаються лише блоки пам’яті, виділені у файлі з іменем, яке відповідає `filename_pattern` у номері рядка `lineno`.

    Якщо inclusive має значення `False` (виключити), ігнорувати блоки пам’яті, виділені у файлі з іменем, яке відповідає `filename_pattern` у номері рядка `lineno`.

  lineno

    Номер рядка (`int`) фільтра. Якщо lineno має значення `None`, фільтр відповідає будь-якому номеру рядка.

  filename_pattern

    Шаблон імені файлу фільтра (`str`). Властивість лише для читання.

  all_frames

    Якщо all_frames має значення `True`, перевіряються всі кадри зворотного відстеження. Якщо all_frames має значення `False`, перевіряється лише останній кадр.

    Цей атрибут не діє, якщо обмеження зворотного відстеження дорівнює `1`. Перегляньте функцію `get_traceback_limit()` і атрибут `Snapshot.traceback_limit`.

### рамка

class tracemalloc.Frame

  Рамка трасування.

  Клас `Traceback` — це послідовність екземплярів `Frame`.

  filename

    Ім’я файлу (`str`).

  lineno

    Номер рядка (`int`).

### знімок

class tracemalloc.Snapshot

  Знімок слідів блоків пам’яті, виділених Python.

  Функція `take_snapshot()` створює екземпляр знімка.

  compare_to(old_snapshot: Snapshot, key_type: str, cumulative: bool = False)

    Обчисліть різницю за старим знімком. Отримати статистику як відсортований список екземплярів `StatisticDiff`, згрупованих за key_type.

    Перегляньте метод `Snapshot.statistics()` для параметрів key_type і cumulative.

    Результат сортується від найбільшого до найменшого за: абсолютним значенням `StatisticDiff.size_diff`, `StatisticDiff.size`, абсолютним значенням `StatisticDiff.count_diff`, `Statistic .count`, а потім `StatisticDiff.traceback`.

  dump(filename)

    Запишіть знімок у файл.

    Використовуйте `load()`, щоб перезавантажити знімок.

  filter_traces(filters)

    Створіть новий екземпляр `Snapshot` із відфільтрованою послідовністю `traces`, filters — це список екземплярів `DomainFilter` і `Filter`. Якщо filters є порожнім списком, поверніть новий екземпляр `Snapshot` із копією трасувань.

    Усі включені фільтри застосовуються одразу, трасування ігнорується, якщо жодні включені фільтри не відповідають йому. Трасування ігнорується, якщо йому відповідає хоча б один ексклюзивний фільтр.

    Змінено в версії 3.6: Екземпляри `DomainFilter` тепер також приймаються в filters.

  classmethod load(filename)

    Завантажте знімок із файлу.

    Дивіться також `dump()`.

  statistics(key_type: str, cumulative: bool = False)

    Отримати статистику як відсортований список екземплярів `Statistic`, згрупованих за key_type:

    key_type | опис
    --- | ---
    `'ім'я файлу'` | ім’я файлу
    `''лінено'` | ім’я файлу та номер рядка
    `'відстеження''` | простежити

    Якщо cumulative має значення `True`, кумулювати розмір і кількість блоків пам’яті всіх кадрів зворотного відстеження трасування, а не лише останнього кадру. Кумулятивний режим можна використовувати лише з key_type, що дорівнює `'filename'` і `'lineno'`.

    Результат сортується від найбільшого до найменшого за: `Statistic.size`, `Statistic.count`, а потім за `Statistic.traceback`.

  traceback_limit

    Максимальна кількість кадрів, що зберігаються у зворотній трасуванні `traces`: результату `get_traceback_limit()` під час створення знімка.

  traces

    Трасування всіх блоків пам’яті, виділених Python: послідовність екземплярів `Trace`.

    Послідовність має невизначений порядок. Використовуйте метод `Snapshot.statistic()`, щоб отримати відсортований список статистики.

### статистика

class tracemalloc.Statistic

  Статистика виділення пам’яті.

  `Snapshot.statistics()` повертає список екземплярів `Statistic`.

  Дивіться також клас `StatisticDiff`.

  count

    Кількість блоків пам’яті (`int`).

  size

    Загальний розмір блоків пам’яті в байтах (`int`).

  traceback

    Зворотне відстеження, де було виділено блок пам’яті, екземпляр `Traceback`.

### StatisticDiff

class tracemalloc.StatisticDiff

  Різниця в статистиці виділення пам’яті між старим і новим екземплярами `Snapshot`.

  `Snapshot.compare_to()` повертає список екземплярів `StatisticDiff`. Дивіться також клас `Statistic`.

  count

    Кількість блоків пам’яті в новому знімку (`int`): `0`, якщо блоки пам’яті було звільнено в новому знімку.

  count_diff

    Різниця кількості блоків пам’яті між старим і новим знімками (`int`): `0`, якщо блоки пам’яті були виділені в новому знімку.

  size

    Загальний розмір блоків пам’яті в байтах у новому знімку (`int`): `0`, якщо блоки пам’яті було звільнено в новому знімку.

  size_diff

    Різниця загального розміру блоків пам’яті в байтах між старим і новим знімками (`int`): `0`, якщо блоки пам’яті були виділені в новому знімку.

  traceback

    Зворотне відстеження, де було виділено блоки пам’яті, екземпляр `Traceback`.

### Слід

class tracemalloc.Trace

  Трасування блоку пам’яті.

  Атрибут `Snapshot.traces` — це послідовність екземплярів `Trace`.

  Змінено в версії 3.6: Додано атрибут `domain`.

  domain

    Адресний простір блоку пам’яті (`int`). Властивість лише для читання.

    tracemalloc використовує домен `0` для відстеження розподілу пам’яті, зробленого Python. Розширення C можуть використовувати інші домени для відстеження інших ресурсів.

  size

    Розмір блоку пам’яті в байтах (`int`).

  traceback

    Зворотне відстеження, де було виділено блок пам’яті, екземпляр `Traceback`.

### Простежити

class tracemalloc.Traceback

  Послідовність екземплярів `Frame`, відсортованих від найстарішого кадру до останнього.

  Трасування містить принаймні `1` кадр. Якщо модулю `tracemalloc` не вдалося отримати кадр, використовується ім’я файлу `"<unknown>"` під номером рядка `0`.

  Коли робиться знімок, зворотне трасування трасування обмежується кадрами `get_traceback_limit()`. Перегляньте функцію `take_snapshot()`. Вихідна кількість кадрів зворотного відстеження зберігається в атрибуті `Traceback.total_nframe`. Це дозволяє дізнатися, чи зворотне відстеження було скорочено обмеженням відстеження.

  Атрибут `Trace.traceback` є екземпляром екземпляра `Traceback`.

  Змінено в версії 3.7: Кадри тепер сортуються від найстаріших до найновіших, а не від останніх до найстаріших.

  total_nframe

    Загальна кількість кадрів, які складали зворотне трасування до скорочення. Для цього атрибута можна встановити значення `None`, якщо інформація недоступна.

  Змінено в версії 3.9: Додано атрибут `Traceback.total_nframe`.

  format(limit=None, most_recent_first=False)

    Відформатуйте трасування як список рядків. Використовуйте модуль `linecache`, щоб отримати рядки з вихідного коду. Якщо встановлено ліміт, відформатуйте ліміт останніх кадрів, якщо ліміт додатний. В іншому випадку відформатуйте найстаріші кадри `abs(limit)`. Якщо most_recent_first має значення `True`, порядок відформатованих кадрів змінюється на протилежний, повертаючи останній кадр першим, а не останнім.

    Подібно до функції `traceback.format_tb()`, за винятком того, що `format()` не містить символів нового рядка.

    Приклад:

        print("Traceback (most recent call first):")
        for line in traceback:
            print(line)

    Вихід:

        Traceback (most recent call first):
          File "test.py", line 9
            obj = Object()
          File "test.py", line 12
            tb = tracemalloc.get_object_traceback(f())