Pull to refresh

Comments 23

В четвёртой задаче я рассуждал, что ничего не мешает создать свой класс class java.lang.Integer implements Iterable и загрузить кастомным класслоадером. Ну или в bootstrap classpath подсунуть. Нет?

java.lang.* классы могут загружаться только в bootstrap класслоадере, с просто кастомным не выйдет. Через bootclasspath вероятно можно, но мой пример все-равно злее: он дергает (x instanceof Iterable<?>) и выводит false.

Ну да, через bootstrap можно и java.lang.Class подменить, тогда все четыре варианта будут возможны :D

Задача 1 — почему область видимости obj заканчивается? Потому что дальше не используется?

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

Пару слов об "области жизни", я думал, что она возможно будет и больше "области видимости".

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

область видимости у obj до конца метода, а вот область жизни заканчивается с последним использованием, да.
Задача 1 — если достигаются состояния отличные от Д, то ситуацию охарактеризовали уж давно — «Горе от ума» называется. Это же просто какой-то бардак на бензоколонке. Я конечно понимаю, что хотели как лучше и «нам надо больше золота» (производительности), но какие-то рамки должны же быть :) А их как проиллюстрировано, уже нет и давно. Бяда

К сожалению, держать переменные "живыми" очень накладно. Компилятор делает все возможное, чтобы минимизировать количество таких переменных в каждый момент времени, чтобы по-больше влезло на регистры процессора, чтобы по-меньше читать память.
Но в целом, если бы вариант D был единственным, мир наш был бы светлее. :)

Если вам специалньо нужно подержать переменную, для этого есть специальный API-метод Reference.reachabilityFence(). Нужен он в реальной жизни исключительно редко, а из-за такой оптимизации вы получаете существенный прирост в производительности вашей программы нахаляву.

Тоже была первая реакция возмущение. А потом немного подумал и понял, что это выглядит очень логичным. Зачем класть в стэк переменную, если после возвращения она больше не будет использоваться? И в большом методе таких переменных может быть куча.
Попробую ответить сразу на 3 сообщения =)

habrahabr.ru/post/350638/#comment_10710890
habrahabr.ru/post/350638/#comment_10710912
habrahabr.ru/post/350638/#comment_10712452

или даже не ответить, а натолкнуть на размышления…

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

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

3. Никакого возмущения, чистая прагматика:

— назовите 3 книги по JAVA где написано, что область действия переменной НЕРАВНА области видимости, давно не заглядывал в книги, надо проверить, но уверен что если 3 наберется, то уже неплохо. А в целом продолжаем учить язык и писать на нём не правильно

— один раз написано — работает? мы сломали принцип? да не, фигня, главное чтоб побыстрее работало =) а принципы и концепции мы молотком по пальцам

— вектор развития языка и его основополагающих принципов (область видимости) как обход и перепрыгивание багов, которые возникли из-за попыток оптимизации?! Это ли наш настоящий джедайский путь

— я обеими клешнями за развитие и ускорение языка, но впереди телеги всё таки пусть катиться концепция. А может я просто ретроград, что мне при таком развитии спокойнее

Я также четко понимаю (так на всякий случай :) что уж ничего не поменять и ИМХО это моё частное мнение, которое ничего не поменяет (всем надо больше золота) и нам всем с этим жить.

Поэтому спасибо ребятам из Excelsior и других не менее крутых контор за то что фиксируете такие тонкости для публики. Интересно про то знать и читать.

И тут же пожелание всем мегагуру, которые пилят для нас VM — ломайте концепции языка пореже, нам всем с этим жить же =)
Ваша развернутая аргументация принята =) спасибо за поддержку. Диспозиция ясна. Пока
назовите 3 книги по JAVA где написано, что область действия переменной НЕРАВНА области видимости

JLS считается за такую книжку? Думаю, ее можно засчитать за три. Вот там в параграфе 12.6.1 (спасибо @shipilev за наводку) сказано:
Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable. For example, a Java compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner.

Лично мне не совсем понятно, почему Вы считаете, что выживание переменных в области видимости, — это какой-то «принцип» или «концепция», которую бессовестно сломали при реализации. Так сделано в C++, например, но нас то это ни к чему не обязывает.

А в чем проблема-то?
(Как это может отразиться на коде?)

Вообще 1 задачка занятная. Логически всё-таки ожидаешь, что, как минимум, объект будет существовать до конца области видимости, а на практике gc пытается сэкономить на всём)
Образцово-показательный набор задачек, браво! Забавно, что в голосовании лидирует самый простой вопрос.

23derevo Вы не думали собирать задачи/вопросы, предлагаемые на конференции, и публиковать их по окончании на сайте?

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

Кстати, «test ecx, ecx» не будет ли всегда true? Насколько я помню asm, test реализован через вычитание. Или тут несколько другой asm?
Сниму вопрос, перепутал с cmp… test, как оказалось, работает через and.

А test используется вместо (более очевидного) cmp по простой причине: он на один байт короче! :)


0:  85 c9         test   ecx,ecx
2:  83 f9 00      cmp    ecx,0x0
Sign up to leave a comment.

Articles