ImageKit в Джанго

eryksun ответил на вопрос №1, и я ответил на вопрос № 3 (оригинал № 4), но теперь давайте ответим на вопрос №2:

Почему он выпускает 50.5mb в конкретный - какова сумма, выпущенная на основе?

blockquote>

. На ее основе лежит, в конечном счете, целая серия совпадений внутри Python и malloc, которые очень трудно предсказать.

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

Или вы можете измерять используемые страницы, которые могут или не могут рассчитывать выделенные, но никогда не затронутые страницы (в системах, которые оптимистически перенастраиваются, например, linux), страницы, которые выделяются, но помечены MADV_FREE и т. д.

Если вы действительно измерение выделенных страниц (на самом деле это не очень полезная вещь, но, похоже, это то, о чем вы спрашиваете), и страницы действительно были освобождены, два обстоятельства, в которых это может произойти: либо вы использовали brk или эквивалент для сокращения сегмента данных (очень редко в настоящее время), или вы использовали munmap или аналогичные для выпуска сопоставленного сегмента. (Существует также теоретически незначительный вариант для последнего, поскольку есть способы освободить часть отображенного сегмента, например, украсть его с помощью MAP_FIXED для сегмента MADV_FREE, который вы сразу же отключите.)

Но большинство программ напрямую не выделяют страницы из памяти; они используют malloc -статический распределитель. Когда вы вызываете free, распределитель может выпустить только страницы в ОС, если вы просто free используете последний живой объект в сопоставлении (или на последних N страницах сегмента данных).

CPython делает это еще более сложным - у него есть настраиваемый 2-уровневый распределитель объектов поверх специализированного распределителя памяти на вверху malloc. (См. исходные комментарии для более подробного объяснения.) И, кроме того, даже на уровне C API, гораздо меньше Python, вы даже не контролируете прямо, когда объекты верхнего уровня deallocated.

Итак, когда вы отпускаете объект, как вы узнаете, собирается ли он выпустить память в ОС? Сначала вы должны знать, что вы выпустили последнюю ссылку (включая любые внутренние ссылки, о которых вы не знали), позволяя GC ее освободить. (В отличие от других реализаций, по крайней мере, CPython освободит объект, как только ему будет разрешено.) Обычно он освобождает по меньшей мере две вещи на следующем уровне вниз (например, для строки вы отпускаете объект PyString и строковый буфер).

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

Если вы сделали , освободите блок чтобы узнать, вызывает ли это вызов free, вы должны знать внутреннее состояние распределителя PyMem, а также то, как оно реализовано. (Опять же, вы должны освободить последний используемый блок в пределах области malloc ed, и даже тогда это может не произойти.)

Если вы сделали free a malloc ed region, чтобы узнать, вызывает ли это munmap или эквивалент (или brk), вы должны знать внутреннее состояние malloc, а также то, как оно реализовано. И этот, в отличие от других, очень специфичен для платформы. (И снова вам, как правило, приходится снимать последнее использование malloc в сегменте mmap, и даже тогда этого может не случиться.)

Итак, если вы хотите понять, почему это случилось, чтобы выпустить ровно 50,5 Мб, вам придется проследить его снизу вверх. Почему malloc удалил страницы размером 50,5 МБ, когда вы сделали эти одни или несколько вызовов free (возможно, чуть больше 50.5 Мб)? Вам нужно будет прочитать вашу платформу malloc, а затем пройти различные таблицы и списки, чтобы увидеть ее текущее состояние. (На некоторых платформах он может даже использовать информацию на системном уровне, что практически невозможно захватить, не делая моментальный снимок системы для проверки в автономном режиме, но, к счастью, обычно это не проблема). И тогда вы должны делайте то же самое на 3 уровнях выше этого.

Итак, единственный полезный ответ на вопрос: «Потому что».

Если вы не используете ограниченную ресурсами (например, встроенную) разработку, у вас нет причин заботиться об этих деталях.

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

1
задан Mariusz Jamro 24 February 2012 в 12:50
поделиться

2 ответа

Ваша модель ProductImage должна наследоваться от imagekit.models.ImageModel вместо models.Model.

1
ответ дан 2 September 2019 в 22:36
поделиться

Это может быть просто ошибка форматирования в вопросе, а не в вашем коде. Но IKOptions должны быть вложены в ваш класс модели:

class ProductImage(models.Model):
    # fields, etc...
    class IKOptions:
        # ...

Кроме того, перед запуском ikflush вы добавляли ImageKit в INSTALLED_APPS в свой файл настроек?

1
ответ дан 2 September 2019 в 22:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: