Иногда, когда вызывается GlobalAddAtom
, я получаю NULL Atom. Форматирование ошибки из GetLastError
показывает «Недостаточно ресурсов памяти для обработки этой команды» , но с использованием Jordi Corbilla Atom Table Monitor Я могу видим, что используется только около 2000 глобальных атомов (1800 из которых являются атомами RWM). Какие другие системные ресурсы требуются GlobalAddAtom
?
Справочная информация. В некоторых случаях мы обнаружили, что Delphi TBitBtn
не будет рисовать (особенно в компьютерных системах, где используются два очень больших и сложных приложения Delphi). были неоднократно открыты и закрыты). Я обнаружил, что FindControl
в vcl.Controls.pas будет считать, что он успешно обнаружил управляющий атом следующим образом: GlobalFindAtom(PChar(ControlAtomString)) = ControlAtom
, но ControlAtom
на самом деле равен NULL, поэтому тест всегда проходит неправильно.
Моей первой идеей было то, что Atom, связанный с ControlAtomString
, не был правильно утилизирован (более ранние версии Delphi действительно имели утечки Global Atom), и что та же самая строка из предыдущего запуска использовалась повторно. Поскольку он состоит из HInstance
и ThreadID
, шансы невелики, но не невозможны. Это был не тот случай. Я мог бы использовать Atom Table Monitor, чтобы убедиться, что имя не использовалось, плюс частота ошибок была слишком высока, чтобы быть конфликтами имен
С этой информацией я решил проверить, могу ли я перехватить любые ошибки Atom и нашел одно перечисленные в моем более кратком вопросе выше.
Минимальный воспроизводимый пример создать нелегко. Приложения, связанные с проблемой, очень велики, и их часто нужно запускать в течение нескольких недель или открывать и закрывать с помощью утилиты тысячи раз, прежде чем проблема поднимает свою уродливую голову.
Как только система переходит в режим, в котором неизвестный системный (глобальный) ресурс исчерпан, проблема может быть воспроизведена с относительной частотой в любом приложении с TBitBtn
. Простое приложение с одним TBitBtn, которое открывается и закрывается несколько раз (часто только 3 или 4 раза), часто не отображает кнопку