FreeBSD demon

(no subject)

Прекрасное (без шуток) начало рабочего дня. Комп меня встретил вот таким окном:


FreeBSD demon

(no subject)

4,692,251,770 байт - объём dvd-диска
4,989,841,408 байт - размер iso с windows 10
С флешки материнка грузиться не умеет

Ищу цензурных слов и не нахожу.
FreeBSD demon

Оптимизации птсо

Есть программка. Мне сказали что она делает решето Эратосфена, но на самом деле это не важно.

int main()
{
    int n = 500000000;
    int *a = new int[n + 1];

    for (int i = 0; i <= n; i++)
    {
        a[i] = i;
    }

    for (int i = 2; i * i <= n; i++)
    {
        if (a[i])
        {
            for (int j = i * i; j <= n; j += i)
            {
                a[j] = 0;
            }
        }        
    }

    delete[] a;
    return 0;
}


Вопрос. Почему ни gcc ни clang даже под -O3 не понимают что это всё можно упростить до return 0; т.к. результат вычислений никуда не используется? Пробовал заменять new/delete на аллокацию на стэке, не помогает.

Update: в GCC был баг, но теперь его починили и ВЖУХ он оптимизирует весь этот код вникуда.
FreeBSD demon

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

Дано: долгоживущее серверное приложение на 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 :(

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



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

Про ноты

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

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

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

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

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


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

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

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

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