|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
К докладу Елизарова я-бы добавил годичной давности семинар по LMAX Disruptor. Там тоже рассматривались общие вопросы оптимизации очередей и отдельно кеши и выравнивание и работа GC. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.03.2016, 23:59 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
Вроде где-то писали/говорили, что есть sun.misc.Contended для этого. Но использовать его стремно. Лучше б они сделали ее не в sun*. Вон пишут, что в девятке от unsafe хотят отказаться, и плюс Reflection.getCallerClass() тоже норовят грохнуть, помоему даже грохали. С этим Contended лучше не связываться, по возможности. армы и x86 процессоров имеют по 64 байта кэшлайна. Насчет остальных архитектур - не знаю. Данные выравнивают, хотя на x86 это необязательно, но это делают все равно - для унификации. Насчет выпиливания полей - помоему это байка-страшилка. jvm позволяет подгружать классы. Где гарантия, что когда-нибудь кто-нибудь не попросит подгрузить класс, а этот класс не полезет в выпиленное поле? никаких ведь FieldSawOutException в этом случае не бросится! Значит и поле должно быть. И даже классы необязательно подгружать, потому что нет гарантий, что в это поле никто не полезет через рефлекшен. ИМХО, максимум что можно - это если сработал escape analyze, то не хранить такие поля в стеке. Но там тоже могут быть приколы с рефлекшеном, так что ИМХО, никакого выпиливания полей вообще не существует. Но инфа не 100% забыл никЕсли честно я утерял нить спора нет никакого спора ... |
|||
:
Нравится:
Не нравится:
|
|||
30.03.2016, 01:31 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
maytonгодичной давности семинар по LMAX Disruptor. а где его взять? ... |
|||
:
Нравится:
Не нравится:
|
|||
30.03.2016, 01:32 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
just_vladimirа в чем профит от аллокации на стеке, вместо аллокации в хипе? Сборщиком мусора. Одна инструкция и память свободна. :) Естественно если это не примитив и нужен деструктор все не так просто. :) ... |
|||
:
Нравится:
Не нравится:
|
|||
30.03.2016, 09:42 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
chabapokmaytonгодичной давности семинар по LMAX Disruptor. а где его взять? Вроде это ... |
|||
:
Нравится:
Не нравится:
|
|||
30.03.2016, 09:46 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
Сергей АрсеньевСборщиком мусора. Одна инструкция и память свободна. :)... ценой жёсткой связи порядка выделения и освобождения памяти. Вы правда готовы работать при таких ограничениях? ... |
|||
:
Нравится:
Не нравится:
|
|||
30.03.2016, 16:01 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
Наваял небольшой JMH бенчмарк, у меня вообще получается, что работа с массивом объектов идет даже быстрее, чем с массивом int'ов, при условии, что все объекты алоцированны подряд (почему пока не разобрался, нужно смотреть асемблерный код, а там на винде нужны лишние приседания для получения бинарника hsdis). Если же при наполнении массива параллельно создавать разные мусорные объекты, чтобы наши целевые объекты не занимали сплошной кусок памяти, то тогда уже начинается серьезная просадка по производительности. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.03.2016, 16:36 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
Некоторые тезисы Елизарова я зафиксил на бумаге. К сожалению перец очень быстро говорит и флудит посторонними мыслями поэтому привожу не цитаты а некоторые купированные фразы. ЕлизаровGC 1. Идеальная ситуация - все объекты короткоживущие. 2. Долгоживущие объекты лежат корректируют только примитивные поля или вообще не меняются. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.03.2016, 16:40 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
maytonЕлизаровGC 1. Идеальная ситуация - все объекты короткоживущие. 2. Долгоживущие объекты лежат корректируют только примитивные поля или вообще не меняются. Смотри. GC это всегда trade off https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/tuning_tradeoffs.html Короткоживущие объекты и перманентный Tenured это как раз способ избавиться от пауз в CMS. Но при этом максимальной производительности такой GC не даст. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.03.2016, 16:47 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
just_vladimirНаваял небольшой JMH бенчмарк, у меня вообще получается, что работа с массивом объектов идет даже быстрее, чем с массивом int'ов, при условии, что все объекты алоцированны подряд (почему пока не разобрался, нужно смотреть асемблерный код, а там на винде нужны лишние приседания для получения бинарника hsdis). Если же при наполнении массива параллельно создавать разные мусорные объекты, чтобы наши целевые объекты не занимали сплошной кусок памяти, то тогда уже начинается серьезная просадка по производительности. ??? Не верю ( C ) Код и что это за "работа" можно посмотреть. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.03.2016, 17:26 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
Leonid Kudryavtsevjust_vladimirНаваял небольшой JMH бенчмарк, у меня вообще получается, что работа с массивом объектов идет даже быстрее, чем с массивом int'ов, при условии, что все объекты алоцированны подряд (почему пока не разобрался, нужно смотреть асемблерный код, а там на винде нужны лишние приседания для получения бинарника hsdis). Если же при наполнении массива параллельно создавать разные мусорные объекты, чтобы наши целевые объекты не занимали сплошной кусок памяти, то тогда уже начинается серьезная просадка по производительности. ??? Не верю ( C ) Код и что это за "работа" можно посмотреть. Да, конечно можно, вполне возможно я где то ошибся в тесте или неверно его интерпретирую или не учитываю влияние GC или еще что нибудь. Работа это сложение int'ов, сравнивал два кейса класс Foo, в нем 3 int'овых филда (a,b,c) и int'овый массив. Код бенчмарка: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116.
Что получилось на выходе: jmh_outputBenchmark (size) (trashSize) Mode Samples Score Score error Units MyBenchmark.intArray 10000 0 avgt 15 38352.732 996.941 ns/op MyBenchmark.intArray 10000 1000 avgt 15 36765.030 2141.320 ns/op MyBenchmark.intArray 10000 10000 avgt 15 34888.401 4205.767 ns/op MyBenchmark.objArray 10000 0 avgt 15 26143.195 1200.436 ns/op MyBenchmark.objArray 10000 1000 avgt 15 215898.867 19812.714 ns/op MyBenchmark.objArray 10000 10000 avgt 15 106175.759 6576.237 ns/op И чисто для objArray с разным trashSize: jmh_outputBenchmark (size) (trashSize) Mode Samples Score Score error Units MyBenchmark.objArray 10000 0 avgt 15 26862.265 1014.527 ns/op MyBenchmark.objArray 10000 100 avgt 15 99337.478 5626.104 ns/op MyBenchmark.objArray 10000 500 avgt 15 188794.983 17663.827 ns/op MyBenchmark.objArray 10000 1000 avgt 15 217068.808 9772.326 ns/op MyBenchmark.objArray 10000 2000 avgt 15 248142.848 6822.500 ns/op MyBenchmark.objArray 10000 3000 avgt 15 251596.867 23983.232 ns/op MyBenchmark.objArray 10000 5000 avgt 15 108882.238 4594.514 ns/op MyBenchmark.objArray 10000 10000 avgt 15 104778.494 9427.842 ns/op Буду рад, если кто-нибудь объяснит наблюдаемые эффекты: 1. Почему int array оказывается медленнее obj array, при условии удачной аллокации объектов? 2. Почему начиная с trashSize = 5000 (может чуть раньше) скорость начинает расти? ... |
|||
:
Нравится:
Не нравится:
|
|||
30.03.2016, 18:08 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
Ах да: java - versionjava version "1.8.0_77" Java(TM) SE Runtime Environment (build 1.8.0_77-b03) Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode) verMicrosoft Windows [Version 6.3.9600] hardwareCore i5 - 2400 3,3 Ghz, L1 - 256 kb, L2 - 1Mb, L3 - 6Mb ... |
|||
:
Нравится:
Не нравится:
|
|||
30.03.2016, 18:15 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
IMHO Вы просто не умеете их готовить. p.s. сейчас с тестом поиграюсь, хотя параметры подсократил. У меня AMD, ждать > 5 мин. на тест - перебор ... |
|||
:
Нравится:
Не нравится:
|
|||
30.03.2016, 19:02 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165.
Код: plaintext 1. 2. 3. 4. 5.
Надеюсь в коде не ошибся. Вроде все 3-и методо intArrayN должны давать одинаковый результат. Не проверял. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.03.2016, 19:22 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
Leonid Kudryavtsev, ну кажется понял свою ошибку, что терял лишнее время на умножениях, из Ваших вариантов с intArray2 не совсем соглашусь, т.к. все таки надо двигаться по массиву честно по одному объекту, а вот intArray3 то что нужно. А как на счет эффектов, когда при увеличении количества мусорных объектов скорость растет, вместо ожидаемого падения? ... |
|||
:
Нравится:
Не нравится:
|
|||
30.03.2016, 19:33 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
just_vladimirLeonid Kudryavtsev, ну кажется понял свою ошибку, что терял лишнее время на умножениях, из Ваших вариантов с intArray2 не совсем соглашусь, т.к. все таки надо двигаться по массиву честно по одному объекту, а вот intArray3 то что нужно. IMHO Дело не в умножении. А в оптимизации JIT проверки на выход за пределы массива just_vladimirА как на счет эффектов, когда при увеличении количества мусорных объектов скорость растет, вместо ожидаемого падения? А где она растет? Мне вообще кажется, что там какие-то очень странные/случайные числа начинают генерироваться. Ну и мусору НУ ОЧЕНЬ много. Патерн > 5000 мусорных объектов на один рабочий - это какой-то трешь. Возможно сборщик мусора паралельно еще какую-то дефрагментацию проводит. До какого-то момента она не сказывается, потом начинает сказываться и ситуация немного улучшается (но все равно ЗНАЧИТЕЛЬНО ХУЖЕ /5 раз/, чем без мусора) IMHO ... |
|||
:
Нравится:
Не нравится:
|
|||
30.03.2016, 20:20 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
Leonid Kudryavtsev, соглашусь, что такое количество мусора перебор. И еще чуток по игрался с мусорными объектами, сделал с шагом в 500 от 0 до 10 000, получил следующую картинку: ... |
|||
:
Нравится:
Не нравится:
|
|||
31.03.2016, 12:36 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
just_vladimirполучил следующую картинку График и цифры на нем наводят на воспоминания.... 4000, 8000... ничего не напоминает? 4000 (правда байт) - размер Memory Page. Фактически при таком кол-ве мусора, получается выравнивание объекта по Memory Page. Мусор оказывается в полностью неиспользуемых страницах, радостно "свопится" (не на диск, а в данном случае просто из кэша процессора или рабочего набора процесса) и больше не мешает ))) IMHO ... |
|||
:
Нравится:
Не нравится:
|
|||
31.03.2016, 12:46 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
Факт интересный своей искусственностью. Но совершенно и 100% чистая синтетика. Никакого практического применения не имеет. IMHO ... |
|||
:
Нравится:
Не нравится:
|
|||
31.03.2016, 12:49 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
Хорошо-бы допилить некоторый хинт или ключевое слово языка. К примеру я инстанциирую синглтон и заведомо знаю что он будет лежать в OldGen/Metaspace. И я хочу заведомо подсказать аллокатору чтобы он не кидал этот объект в Eden а сразу ложил туда куда мне нужно. Код: java 1. 2. 3. 4. 5. 6. 7.
По сути на уровне разработки дать больше инструментов для управления аллокацией. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.03.2016, 13:20 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
maytonК примеру я инстанциирую синглтон и заведомо знаю что он будет лежать в OldGen/Metaspace. И я хочу заведомо подсказать аллокатору чтобы он не кидал этот объект в Eden IMHO бессмысленный хинт. Экономия копеек. Eden и так крайне быстр. Скорее надо наоборот, подсказка, что объект временный. Но тогда такую подсказку нужно будет у 99% объектов указывать, а это - треш и угар. Ну и разумеется, при недостатке памяти, у RunTime будет не богатый выбор: или падать с out of memory или все равно, не смотря на подсказку, в old вытеснить. Т.ч. тоже механика работы такой подсказки не понятна Возможно, можно было бы на уровне VM сделать Thread кучи. Т.е. все объекты созданные в рамках Thread относятся к "своей" кучи. При смерти Thread или по каким-то событием (например, завершение обработки HTTP запроса в рамках Web/Application Сервера), выжившие объекты переносятся в Old, плюс чистится мусор относящийся к данному Thread в Old. Получаем: 1. Для разных HTTP запросов (с разным временем выполнения) - можно сделать свою метрику обработки Eden области. Меньше сессионного мусора будет уходить в Old 2. Процесс можно осмысленно побить по кусочкам. Получим своего рода incremental mark sweep. 3. Потенциально, можно сделать 2-х уровневый Eden. Если места в Eden Thread'а/HTTP-запроса мало, туда добавляются блоки из Old. Eden для конкретного Thread'а/HTTP-запроса расширяется. По окончанию Thread'а/HTTP-запроса, вся область грохается, а выжившие объекты перемешаются в Old. Нужно читать более подробно Читать: 1. о G1 garbage коллектор, вроде там похожая идея была. 2. как работает процесс пометки живой/мертвый объектов в Eden области. Х.з. Но minor GC крайне быстрый. Если пометка живой/мертвый в рамках привязки к Thread/HTTP-запросу можно сделать очень быстро, то осмысленно. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.03.2016, 13:43 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
Развивая идею. Матричный Eden. Или сегментированный. Поскольку чистка это в общем случае решение задачи из области теории графов (проверка достижимости узлов из некого корня) то ее надо оптимизировать исходя из сходных по своей природе узлов (объектов). Например мы деаем какую-то активность. И много всего аллоцируем. А после этого чистим всё. Чтобы не флудить в общем eden мы аллоцируем сегмент и работаем в нем. Во время фазы уборки GC учитывает наличие связей только внутри сегмента и быстро убирает мусор не отвлекаясь на анализ всего графа. По сути чистит подграф. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.03.2016, 13:57 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
mayton...Во время фазы уборки GC учитывает наличие связей только внутри сегмента и быстро убирает мусор не отвлекаясь на анализ всего графа. По сути чистит подграф. Не отвлекаться не может. Т.к. ссылки могли быть переданы в какой-то "глобальный" объект, и "только внутри" не получится. Но в случае с eden, он как-то такие ситуации разгуливает. Вместо одного глобального eden, хочется много мелких "локальных". На уровне thread, http-запроса и т.д. В принципе, даже некоторые методы можно было бы помечать локально-эденистыми. Где известно, что будет идти большое выделение памяти внутри. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.03.2016, 14:15 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
При этом minor (eden) GC вроде работает в параллельном режиме. Т.ч. даже VM на такую уборку можно не останавливать. А делать в параллель, в фоне. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.03.2016, 14:18 |
|
Java 8 - уже не совсем Java?
|
|||
---|---|---|---|
#18+
Leonid Kudryavtsev Возможно, можно было бы на уровне VM сделать Thread кучи. Т.е. все объекты созданные в рамках Thread относятся к "своей" кучи. Так оно так и работает насколько я себя помню, у каждого Thread есть свой TLAB(thread local allocation buffer) ... |
|||
:
Нравится:
Не нравится:
|
|||
31.03.2016, 14:19 |
|
|
start [/forum/topic.php?fid=59&msg=39203841&tid=2120495]: |
0ms |
get settings: |
11ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
33ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
57ms |
get tp. blocked users: |
1ms |
others: | 13ms |
total: | 150ms |
0 / 0 |