Xcode тысяч утечек памяти в системных библиотеках - PullRequest
0 голосов
/ 05 мая 2019

Я выполнил инструментарий в своем приложении для проверки утечек памяти, поскольку прошло несколько месяцев (по крайней мере) с момента последней проверки, и я добавил новую функцию в свое приложение и произвел рефакторинг некоторого кода. Когда я начал запускать, все выглядело хорошо с первой проверкой (загружен контроллер основного вида, и он имеет 6 кнопок, метку и 6 пользовательских представлений пользовательского интерфейса, которые по сути являются просто метками с некоторыми изображениями), но вторая проверка поразила меня, говоря, у меня было 1460 новых утечек. Это казалось действительно высоким, когда все, что я делал в приложении, это нажимал кнопку, которая нажимала на второй контроллер вида (хотя и не простой, но он тоже не делал ничего особенного).

Взглянув на список утечек, только 7 были помечены как ошибки моего приложения, а остальные 1453 - следующие системные библиотеки:

  • AppSupport
  • BackBoardServices
  • плинтус
  • CFNetwork (как? Я даже не делаю никаких сетей ...)
  • ColorSync
  • CoreGraphics
  • CoreUI
  • Основание (вероятно, ~ 300 утечек)
  • FrontBoardServices
  • GraphicsServices
  • ImageIO
  • ManagedConfiguration
  • PrototypeTools
  • QuartzCore
  • UIFoundation
  • UIKitCore (~ 700 утечек, примерно как половина)
  • UIKitServices
  • libAccessibility.dylib
  • libnetwork.dylib
  • libsystem_pthread.dylib
  • vimage

Чем больше я делаю в приложении, тем больше системных библиотек появляется, и я могу легко добиться нескольких тысяч утечек.

Глядя на все различные трассировки стека, любопытно, что около половины из них (из всех случайных трасс, на которые я смотрел) имеют одинаковые первые четыре или пять вызовов, начиная с функций lookUpImpOrForward или _objc_msgSend_uncached, как видно на скриншоте ниже.

Instruments memory leak run

Когда я смотрю на утечки, вызванные моим приложением, все они имеют эти пять функций в верхней части трассировки стека, а функции моего приложения чуть ниже них. Когда я дважды щелкаю по своим функциям в трассировке стека, чтобы взглянуть на строки кода, которые распределяют утечку памяти, меня переводят в строки типа

label = [[UILabel alloc] init];

или

CGPoint point = CGPointMake(bottomBar.frame.origin.x + 70,
                            bottomBar.frame.origin.y);

первый из которых должен быть совершенно безопасным, так как я не делаю ничего необычного в этом классе памяти, и я понятия не имею, как второй может вообще быть вовлечен в утечку памяти, так как он не имеет дело с любые указатели.

Чтобы попытаться сузить причину, я снова побежал и нажал другую кнопку, которая привела меня к контроллеру представления, который ничего не делает при загрузке и содержит только панель навигации, 6 кнопок (4 с изображениями) и 3 метки - довольно минимальный базовый материал. Тем не менее, я получил 828 новых утечек на чеке после нажатия кнопки.

В дальнейшем я создал совершенно новый проект приложения с одним представлением в Xcode и продублировал первый контроллер представления. Я поместил кнопку на первом контроллере представления, у которого было шоу-шоу второму, и я поместил метку на втором контроллере представления. Вы можете найти код в https://github.com/AdamNEvans/LeakySampleApp. Запуск этого в инструментах дает мне колоссальные 237 утечек памяти после нажатия на контроллер второго вида. Как?!?!?

Я не помню, чтобы когда-либо видел почти столько утечек, когда выполнял инструментарий утечки памяти в прошлом. Я уверен, что я делаю что-то не так, что вызывает по крайней мере некоторые из этих утечек, но тот факт, что их так много и так много не включают в себя мой код, заставляет меня думать, что я либо создаю объекты неправильно в кучу разных мест (я не уверен, как я могу испортить вызовы alloc и init), или ошибка была введена в системные библиотеки и наносит ущерб (мое предположение было бы что-то в этих общих пяти функционирует на вершине лота следов стека).

90% утечек меньше 1 КБ, поэтому приложение может выжить в течение длительного времени с этими утечками, но это по-прежнему беспокоит меня, поскольку это служебное приложение, в котором люди могут потенциально проводить часы.

У меня включен ARC, и я использую Xcode 10.2.1, когда запускаю свое приложение на физическом iPad Air 2 с iOS 12.2.

Есть идеи?

...