?

Log in

No account? Create an account

(без темы)

май. 10, 2019 | 11:56 pm

Запилил статейку на Хабр: "Топологическая" сортировка графа с циклами

Ссылка | Оставить комментарий |

Java жрёт память как не в себя? Ну, не совсем Java и не совсем в себя

ноя. 29, 2018 | 05:07 pm

Дано: долгоживущее серверное приложение на Java (https://github.com/bozaro/git-as-svn). Приложеньке выдано 12GB под Java-объекты (-Xmx12g). Сверху ожидается некоторый оверхед от инфраструктурных вещей которые JVM обеспечивает приложению (сборка мусора, компиляция байткода в натив, етц). Ну не знаю, 10-20% кажется разумным. Также есть сервер с Ubuntu 14.04 о 24 ядрах на котором запущено это приложение под Oracle JDK 1.8u45.

Далее запускаем приложение и видим что оно под нагрузкой улетает хорошо за 40GB резидентной памяти (колонка RES в top(1)) и в какой-то момент за ним приходит OOM killer. 40GB, Карл, при -Xmx12g!

"Течёт память" подумали мужики и пошли чесать репу.

1. Первым делом была обновлена JVM 1.8u45 -> 1.8u181 (наисвежайшая на тот момент). Помогло никак.

2. Почитали логи GC. Всё чинно-мирно, внутри хипа полно свободного места и ограничитель в 12GB на месте.

3. "Память жрёт что-то за пределами heap'а" подумали мужики. Нашли статью про поиск утечек в DirectBuffer'ах при помощи jxray. Сняли хип-дамп, насчитали несколько десятков MB памяти аллоцированной DirectBuffer'ами. Мало, не то.

4. "Память жрёт что-то в других потрохах JVM". Нашли механизм Native Memory Tracking, который позволяет отслеживать на что JVM потратила память за пределами хипа. Выяснили что в момент когда процесс суммарно занимает 20GB, Native Memory Tracking может нам рассказать куда потрачено 14.8GB из них (это, конечно, не 10-20% оверхеда, а вполне себе 25%). Где ещё 5GB неясно.

5. "Память ТЕЧЁТ?" Нашли статью про поиск утечек в нативном коде JVM через компиляцию jemalloc с включенной профилировкой, запуском JVM под этим jemalloc и вдумчивым курением логов. Можно, но как-то сложно и грустно. Запомнили мысль и пошли дальше, искать ключи под фонарём.

6. "Память жрёт что-то за пределами JVM". Каким-то невероятным чудом нашли багрепорт в другом Java-проекте (presto) который тоже испытывал проблемы с неудержимым потреблением памяти. И открылось замечательное. glibc берёт память у ядра большими кусками и очень нехотя отдаёт их обратно. Причём количество "недоотданной памяти" зависит от количества ядер в системе, размеров порций которыми приложение делает malloc и чёрт знает чего ещё. Получить внятного ответа на вопрос "сколько максимум памяти может занимать одна арена" пока не вышло. Больше всего страдают приложения с большим количеством потоков которое аллоцирует/деаллоцирует память большими порциями. Как бы то ни было, уменьшение MALLOC_ARENA_MAX с дефолтных 16 до 4 привело к тому что свыше 20GB приложение расти перестало.

7. Попутно было обнаружено что в приложении живёт (в основном, естественно, спит) порядка 100 потоков:

30 порождённых самим приложением
5 от JVM C1 compiler
9 от JVM C2 compiler
24 "gang worker" для сборщика мусора G1
20 "G1 Concurrent Refinement Thread" для сборщика мусора G1

Тут в общем-то возникает справедливый WTF - зачем сборщику мусора потоков почти вдвое больше чем ядер в системе. Внятного ответа пока нет, зато нашёлся баг в JVM по которому складывается впечатлнение что столько много "G1 Concurrent Refinement Thread" не нужно и вообще баг. Нужно ли столько gang worker'ов тоже неясно. И нужно ли C2 compiler'у?

8. Финальное решение: уменьшить MALLOC_ARENA_MAX до единицы. Уменьшить количество "G1 Concurrent Refinement Thread". Уменьшить количество потоков запускаемых самим приложением (примерно вдвое, причём совершенно безболезненно для самого приложения). Вообще кажется так что MALLOC_ARENA_MAX будет доставлять боль многим большим долгоживущим многопоточным серверным приложениям.

Мораль: раньше надо было тюнить сборщик мусора и количество одновременно открытых файловых дескрипторов, а теперь ещё и glibc :(

Бонусные ссылки по теме:



Кажется, это самый масштабный продолб оперативы вникуда который мне когда-либо встречался.
Метки: ,

Ссылка | Оставить комментарий {3} |

Про ноты

сент. 21, 2018 | 08:23 pm

Решил тут вдруг научиться играть на пианино, но понял что без большого количества тренировок очень, блин, сложно читать ноты.

Что, собственно, меня не устраивает: нельзя просто посмотреть на ноту и понять какую клавишу надо нажимать. Нужно: 1. Поискать от интересующей ноты обратно до начала такта эту же ноту с диезом/бемолем/бекаром. Если такая нота есть, применить её сдвиг тона к текущей ноте. 2. Если такой ноты нет, посмотреть диезы-бемоли у этой же ноты при ключе. Если есть, соответственно применить. "Удобства" добавляет тот факт что при ключе ноты в верхней октаве, поэтому её ещё поискать надо.

Короче, это всё боль, страдание и унижение.

Предлагаю другое решение:

  1. Выбрасываем знаки при ключе
  2. Выбрасываем знаки при ноте
  3. Для повышения ноты на полтона вместо кружка ноты рисуем треугольник смотрящий углом вверх. Для понижения, соответственно, смотрящий вниз
  4. Заливка нот чёрным, хвостики и прочая хрень остаётся без изменений


Собственно, всё. Теперь вопрос - есть ли у этого подхода хоть какие-то объективные минусы по сравнению с диезами?

P.S. А ещё оказывается есть дубль-диезы, дубль-бемоли, бекар-диезы и бекар-бемоли. Но вроде бы в моей системе записи эта дичь тоже не нужна.

P.P.S. А кто-нибудь знает причину по которой клавиши разделены на черные/белые именно так как это сделано? Почему, например, не используется простое чередование белый-черный-белый-черный? Оно бы например сводило процесс транспонирования просто к переносу рук.

Есть мысль ещё более сильно отрефакторить ноты, с отказом от названий, а вместо этого оперируя понятиями "+N полутонов", но пока не до конца продумал формат записи. И понадобится переделать клавиатуру пианино.

Ссылка | Оставить комментарий {1} |

Развитие гугл-переводчика за 2 года

сент. 21, 2018 | 06:05 pm

2016-ый год





2018-ый год







Also, big-endian на сегодняшний день == "большой обратный порядок байт".

Ссылка | Оставить комментарий |

Микрософт начал превращать гитхаб в говно

июн. 18, 2018 | 09:09 am

Из мобильной версии пропала кнопка Subscribe на пулл-реквест :(

Написал в саппорт, сказали что ETA нету. Но вы держитесь.
Метки:

Ссылка | Оставить комментарий {1} |

Хайлоад, ёба, пхп-стайл

июн. 14, 2018 | 01:14 am

https://habr.com/company/badoo/blog/413991/
А теперь мы посчитаем MD5, переведём в HEX, возьмём первые 8 символов и будем использовать их для определения уникальности содержимого файла. А git придурки какие-то какие-то писали, он нам не подходит.

Ссылка | Оставить комментарий {6} |

Всё что нужно знать о CryEngine

май. 20, 2018 | 02:56 pm

9 причин не работать на CryEngine
Метки:

Ссылка | Оставить комментарий |

(без темы)

май. 10, 2018 | 12:49 pm

Microsoft’s implementation of a three-state boolean: 5 states, 3 of which are not supported.

https://msdn.microsoft.com/en-us/library/microsoft.office.core.msotristate.aspx

Ссылка | Оставить комментарий |

Программистско-лингвистическое

мар. 2, 2018 | 02:48 pm

Сегодня внезапно понял что rake которым пользуются рубисты - это же ГРАБЛИ.
Метки:

Ссылка | Оставить комментарий |

(без темы)

янв. 6, 2018 | 12:13 pm

А что мешает легально делать так:

1. Устраиваемся на работу
2. Подписываем соглашение о неразглашении коммерческой тайны
3. Получаем доступ к коду всяких сервисов компании
4. Копируем код на флешку/whatever (но никому не разглашаем)
5. Увольняемся
6. Ждем истечения сроков NDA
7. Публикуем код на GitHub

Непонятно, нарушает ли что-то пункт 4, но кажется что нет.

Also, в некоторых странах не работает пункт 6, потому что допустимы бессрочные NDA.

Ссылка | Оставить комментарий {1} |