Хотя я еще не большой поклонник Ruby, я нахожу, что динамические языки действительно замечательные и мощные инструменты.
идея, что нет никакой проверки типа и объявления переменной, не является слишком большой проблемой действительно. По общему признанию Вы не можете зафиксировать эти ошибки до времени выполнения, но для опытных разработчиков это не действительно проблема, и когда Вы действительно делаете ошибки, они обычно легко фиксируются.
Это также вынуждает новичков считать то, что они пишут более тщательно. Я знаю изучение, что PHP учила меня быть более внимательным к тому, что я на самом деле вводил, который улучшил мое программирование даже на скомпилированных языках.
Хорошие IDE дадут достаточно intellisense для Вас, чтобы знать, была ли переменная "объявлена", и они также пытаются сделать некоторый вывод типа для Вас так, чтобы можно было сказать, какова переменная.
питание того, что может быть сделано с динамическими языками, действительно, что делает их такой забавой работать с, по-моему. Несомненно, Вы могли сделать то же самое на скомпилированном языке, но потребуется больше кода. Языки как Python и PHP позволяют Вам разработать за меньшее время и получить функциональную кодовую базу быстрее большую часть времени.
И для записи, я - полностью занятый разработчик.NET, и я люблю скомпилированные языки. Я только использую динамические языки в свое свободное время для получения дополнительной информации о них и лучше мне как разработчик..
Думаю, ваш анализ выглядит правильным. Я не эксперт по gc
, поэтому всякий раз, когда у меня возникает подобная проблема, я просто добавляю вызов gc.collect ()
в подходящем, некритичном по времени месте, и забудьте об этом.
Я бы посоветовал вам вызвать gc.collect ()
в ваших представлениях и посмотреть, как это повлияет на ваше время отклика и использование памяти.
Примечание. также этот вопрос , который предполагает, что установка DEBUG = True
съедает память, как будто срок ее продажи почти истек.
Имеет ли смысл сказанное выше, или мне нужно искать проблему в другом месте? Это просто досадная случайность, что важные данные хранятся так долго в этом конкретном случае использования?
Да, это имеет смысл. И да, есть и другие вопросы, которые стоит рассмотреть. Django использует threading.local
в качестве основы для DatabaseWrapper
(и некоторые участники используют его, чтобы сделать объект запроса доступным из мест, где он не передан явно). Эти глобальные объекты выдерживают запросы и могут сохранять ссылки на объекты до тех пор, пока в потоке не будет обработано какое-либо другое представление.
Могу ли я что-нибудь сделать, чтобы избежать этой проблемы. Я уже вижу некоторый потенциал для оптимизации представления, но, похоже, это решение с ограниченным объемом - хотя я также не уверен, что я использую в качестве общего; Насколько целесообразно, например, вызывать gc.collect () или gc.set_threshold () вручную?
Общий совет (возможно, вы его знаете, но в любом случае): избегайте циклических ссылок и глобальных переменных (включая threading.local
). Попробуйте разорвать циклы и очистить глобальные объекты, когда дизайн django не позволяет их избежать. gc.get_referrers (obj)
может помочь вам найти места, требующие внимания. Другой способ - отключить сборщик мусора и вызывать его вручную после каждого запроса, когда это лучше всего делать (это предотвратит перемещение объектов в следующее поколение).
Я не думаю, что есть способ сделать gc.get_objects () по генерации, т.е. получать объекты только из поколения 2, например?
К сожалению, это невозможно с интерфейсом gc
. Но есть несколько путей. Вы можете рассматривать конец списка, возвращаемого только gc.get_objects ()
, поскольку объекты в этом списке сортируются по поколениям. Вы можете сравнить список со списком, возвращенным из предыдущего вызова, сохранив на них слабые ссылки (например, в WeakKeyDictionary
) между вызовами. Вы можете переписать gc.get_objects ()
в своем собственном модуле C (это просто, в основном программирование копированием и вставкой!), Поскольку они сохраняются путем генерации внутри, или даже обращаться к внутренним структурам с помощью ctypes
] (требует достаточно глубокого понимания ctypes
).
WeakKeyDictionary
) между вызовами. Вы можете переписать gc.get_objects ()
в своем собственном модуле C (это просто, в основном программирование копированием и вставкой!), Поскольку они сохраняются путем генерации внутри, или даже обращаться к внутренним структурам с помощью ctypes
] (требует достаточно глубокого понимания ctypes
). в WeakKeyDictionary
) между вызовами. Вы можете переписать gc.get_objects ()
в своем собственном модуле C (это просто, в основном программирование копированием и вставкой!), Поскольку они сохраняются путем генерации внутри, или даже обращаться к внутренним структурам с помощью ctypes
] (требует достаточно глубокого понимания ctypes
).