Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Лекция 11. Динамическая типизация и сборка мусора. Критика ООП

Лекция 11. Динамическая типизация и сборка мусора. Критика ООП

Oleg Dashevskii

May 16, 2016
Tweet

More Decks by Oleg Dashevskii

Other Decks in Education

Transcript

  1. SMALLTALK • Появился в 1970-е гг. • Всё — объект

    (строки, числа, true и false, …). Работа программы — посылка сообщений. Любое сообщение может быть послано любому объекту. • Всё доступно для изменения (без остановки, компиляции и перезапуска). • Динамическая типизация. • Сборка мусора. Байт-код.
  2. | x sum | 42 factorial. "1405006117752879898543142606244511569936384000000000" x := 2

    raisedTo: 4. "16" 'hello world' indexOf: $o startingAt: 6. "8" 3 factorial + 4 factorial between: 10 and: 100. "true" x := x > 10 ifTrue:[ 'greater' ] ifFalse: [ 'less or equal' ]. "'greater'" sum := 0. 1 to: 10 do: [ :i | sum := sum + i. ]. sum. "55"
  3. | aString vowels | aString := 'This is a string'.

    vowels := aString select: [:aCharacter | aCharacter isVowel]. "iiai"
  4. ДИНАМИЧЕСКАЯ ТИПИЗАЦИЯ • Каждая переменная хранит в себе не только

    значение, но и класс объекта! • Объект «класс» (синглтон) принадлежит классу «метакласс». В этом объекте хранятся все свойства класса (имена переменных, методы, ссылка на родительский класс…)
  5. ОБРАБОТКА СООБЩЕНИЙ • Отправка сообщения Msg объекту Obj. • Проверяем,

    объявлен ли метод в классе (Obj class). Если нет, ищем объект в родительском (суперклассе) и т.д. по всей иерархии до самого Object. • Если ничего не найдено, посылаем специальное сообщение MessageNotUnderstood. • Вся система полностью динамическая. В любой момент можно изменить или добавить метод у любого класса!
  6. JAVASCRIPT var person = { firstName: 'Ivan', lastName: 'Petrov', ivan:

    function() { return true } }; var Person = { fullName: function() { return this.firstName + ' ' + this.lastName; } }; person.__proto__ = Person; console.log(person.fullName()); // "Ivan Petrov" console.log(person.ivan()); // true
  7. СБОРКА МУСОРА • Решает проблемы: • Слишком раннее освобождение (когда

    на освобождаемую структуру есть ссылки). • Многократное освобождение. • Утечки памяти (когда теряется указатель на выделенную память).
  8. • Недостатки: • Поиск памяти для освобождения требует ресурсов CPU.

    • Вызов GC часто происходит в непредсказуемый момент и длится непредсказуемое время. • По оценке, требуется в 5 раз больше памяти, чтобы программа работала примерно с той же скоростью, что и при ручном управлении памятью.
  9. MARK-AND-SWEEP • У каждого объекта есть флаг (по умолч. false).

    • Шаг 1 (Mark). Отталкиваясь от «корней» (переменные в стеке, глобальные объекты), идём по ссылкам и помечаем объекты как используемые (true). • Шаг 2 (Sweep). Сканируем всю память, ищем непомеченные объекты и освобождаем их, а у помеченных сбрасываем флаг в false. • Недостатки: • На время исполнения вся система должна замереть. • Нужно прочесать всю память, что создаёт нагрузку на подсистему виртуальной памяти в ОС.
  10. ТРЕХЦВЕТНАЯ МАРКИРОВКА • Белый список («приговорённые»). Объекты-кандидаты на удаление. •

    Чёрный список. Объекты, до которых можно добраться от «корней» и у которых нет ссылок на объекты из белого списка. • Серый список. Объекты, достижимые от «корней», но про которые неизвестно, содержат ли они ссылки на объекты из белого списка. • Алгоритм: • Выбрать объект из серого списка и переместить его в чёрный, пометив все белые объекты, на которые он ссылается, серым. Повторять, пока серый список не опустеет. • Удалить все объекты из белого списка.
  11. • Такой алгоритм может работать «на ходу», систему останавливать не

    надо. • Отсутствует шаг «Mark». Все перемещения объектов между списками можно осуществлять также по ходу выполнения программы.
  12. ПОДСЧЁТ ССЫЛОК • Для каждого объекта ведётся учёт количества ссылок

    на него. • Если количество ссылок равно нулю, объект можно освободить (или переместить в список освобождаемых).
  13. • Преимущества: • То, что объект можно уничтожить, становится явным

    сразу. • Легко реализуется. • Производительность системы слабо зависит от количества свободной памяти. • Недостатки: • Слишком частые обновления. • Проблема циклических ссылок. • Нельзя перемещать объекты.
  14. ПОКОЛЕНИЯ ОБЪЕКТОВ • Наблюдения: • Большая часть объектов «умирает молодыми».

    • Более 90 % освобождаемых объектов возникает со времени прошлого цикла GC. • Если объект пережил GC, скорее всего, он вряд ли будет освобожден. • Разделяем объекты по поколениям.
  15. • Все объекты начинают в Gen0. • Те из Gen0,

    что пережили цикл GC, переносятся в Gen1. Аналогично Gen1 -> Gen2. • Gen0 чистится чаще всех.
  16. – Джо Армстронг, создатель языка Erlang. «Проблема с ОО-языками в

    том, что они тащат с собой весь этот невидимый багаж. Вам нужен банан, а вам дают обезьяну, держащую банан, и в довесок к ней джунгли целиком». Модульность, повторное использование кода?
  17. – Александр Степанов, создатель STL «ООП кажется мне технически необоснованным.

    Оно пытается осуществить декомпозицию мира на интерфейсы, которые варьируются по одному типу. Чтобы иметь дело с реальными задачами, нужны множественные алгебры — семейства интерфейсов, захватывающих несколько типов.
 Я нахожу ООП и философски необоснованным. Оно утверждает, что всё есть объект. Даже если это так, это не очень интересно: сказать, что всё есть объект — значит не сказать ничего». Всё есть объект? Полиморфизм по одному типу?
  18. ;; Определение мультиметода. Он выбирает реализацию (defmulti greeting (fn [x]

    (get x "language"))) ;; Реализация для English (defmethod greeting "English" [params] "Hello!") ;; Реализация для French (defmethod greeting "French" [params] "Bonjour!") ;; Реализация по умолчанию (defmethod greeting :default [params] (throw (IllegalArgumentException. (str "I don't know the " (params "language") " language")))) (def english-map {"id" "1", "language" "English"}) (def french-map {"id" "2", "language" "French"}) (def spanish-map {"id" "3", "language" "Spanish"}) => (greeting english-map) "Hello!" => (greeting french-map) "Bounjour!" => (greeting spanish-map) java.lang.IllegalArgumentException: I don't know the Spanish language Мультиметоды на Clojure
  19. (defmulti bat (fn ([x y & xs] (mapv class (into

    [x y] xs))))) (defmethod bat [String String] [x y & xs] (str "str: " x " and " y)) (defmethod bat [String String String] [x y & xs] (str "str: " x ", " y " and " (first xs))) (defmethod bat [String String String String] [x y & xs] (str "str: " x ", " y ", " (first xs) " and " (second xs))) (defmethod bat [Number Number] [x y & xs] (str "number: " x " and " y)) ;; Примеры вызова (bat "mink" "stoat") ;; => "str: mink and stoat" (bat "bear" "skunk" "sloth") ;; => "str: bear, skunk and sloth" (bat "dog" "cat" "cow" "horse") ;; => "str: dog, cat, cow and horse" (bat 1 2) ;; => "number: 1 and 2"
  20. – Пол Грэм, венчурный капиталист, создатель Viaweb «Популярность ООП в

    больших компаниях связана с тем, что оно соответствует их стилю разработки ПО. В них работают большие (и часто меняющиеся) группы программистов- посредственностей. ООП создаёт дисциплину, чтобы никто не мог наломать слишком много дров. Цена такова, что в программах слишком много протоколов (базовых классов) и дублирования. Но это не очень высокая цена для крупных компаний, поскольку их ПО и так перегружено, да и дублирования в нём всё равно предостаточно». Модульность, говорите?
  21. – Стив Йегги, разработчик и блоггер «ООП ставит во главу

    угла Существительные. Зачем из кожи вон лезть, чтобы поставить одну из частей речи на пьедестал? Почему одна концепция должна превалировать над другой? ООП отнюдь не уменьшает важность глаголов в том способе, котором мы думаем. Оно даёт странный, ассиметричный взгляд на вещи». Всё есть объект?
  22. – Рич Хики, создатель языка Clojure «Объектные системы — слишком

    упрощённые модели реального мира. ООП неспособно правильно моделировать время, что становится проблемой, поскольку программные системы приобретают всё больший параллелизм». Всё есть объект?
  23. – Эрик Рэймонд, разработчик Unix, сторонник OpenSource «ОО-концепция показала себя

    ценной в разработке графических систем, GUI и в моделировании. Но … значительные преимущества в других областях не проявились. Полезно понять почему. 
 … ООП слишком часто называлось Единственно Верным Решением для управления сложностью. 
 
 … ОО-языки делают абстракцию лёгкой, даже слишком. Они приветствуют архитектуры с толстым слоем «клея» и тщательно созданными слоями. Это хорошо, когда задача сложна… но даёт неприятный эффект, если разработчики делают простые вещи сложным способом, просто потому что могут.
 … Правила простоты, ясности и прозрачности нарушаются повсеместно… … Одна из главных сложностей в дизайне в стиле Unix — как соединить вместе преимущества отделённости (упрощение и обобщение задач…) с преимуществом тонкого уровня «клея» и неглубоких, плоских, прозрачных иерархий кода и дизайна».