Как стать автором
Обновить
26
0

Пользователь

Отправить сообщение
После прочтения решил оставить тут в комментариях ссылку на эту историю.
ithappens.me/story/10297
Она у меня в закладках, иногда перечитываю, чтобы не забывать.
objid: «0x» + parseInt(objectid(x)).toString(16)
Извиняюсь, не успел отредактировать, вот кликабельная ссылка: http://mail-archives.apache.org/mod_mbox/tomcat-users/201506.mbox/%3C556EC74A.5040306%40apache.org%3E
UPD 3: markt в мейлинг-листе томкета отвечал на вопрос, какого чёрта в томкете два коннекшн-пула одновременно (tomcat-jdbc и одновременно DBCP, и почему внезапно в восьмом томкете DBCP стал выгоднее): http://mail-archives.apache.org/mod_mbox/tomcat-users/201506.mbox/%3C556EC74A.5040306%40apache.org%3E.
Плюс в карму за терморектальный криптоанализатор на второй картинке статьи. Бедная Java…
Да, есть такое.
Мой путь приводит к «несозданию» (да, да, к автоудалению) этого флага в принципе, и убирать ничего не требуется.
Находил такой прикол, когда ставил однажды Synaptics-тачпад-драйвер на ноуте.
Распакованный виндовой утилитой драйвер после инсталляции задавал дурацкие вопросы при старте своих утилит.
Сразу стало понятно, кто виноват.
После этого случая я начал делать финт ушами на домашнем компе: gpedit.msc — Конфигурация пользователя — Административные шаблоны — Компоненты Windows — Диспетчер вложений — Удаление сведений о зоне происхождения вложений — Включить — Ок.
А то эти вопросы дурные ни к чему на однопользовательском компе. А на группе файлов этот признак не убирается (пачкой), по одному сиди разблокируй (Win 7).
Отлично, как раз то, что хотелось узнать про MAT. Благодарю!
Хотя нет, я соврал, я пропустил заветную строчку «Dumping heap to ./java_pid6902.hprof ...». Однако приложение всё равно «выживает». Возможно, такие конструкции с перехватом Throwable как раз и являются причиной варианта «приложение всё ещё живое, но не отвечает».
Заголовок спойлера
$ java -Xmx256m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=. TestOOM
мар 23, 2015 5:26:35 PM TestOOM main
INFO: Press Enter to make OOM...

java.lang.OutOfMemoryError: Java heap space
Dumping heap to ./java_pid6902.hprof ...
Heap dump file created [85808247 bytes in 0,406 secs]
мар 23, 2015 5:26:36 PM TestOOM main
SEVERE: Here is an some Throwable, printing it and ignoring.
java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOf(Arrays.java:2367)
        at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:130)
        at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:114)
        at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:415)
        at java.lang.StringBuilder.append(StringBuilder.java:132)
        at TestOOM.main(TestOOM.java:17)

мар 23, 2015 5:26:36 PM TestOOM main
INFO: I am still alive! Press Enter to quit...
Да, его можно перехватить, выдать в лог, и не пропустить дальше. В консоль и лог OOM в этом случае попадёт, но JVM о нём вроде как не узнает.
Почему перехват Throwable нужно делать с полным знанием дела
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;

public class TestOOM {
    private static final Logger LOGGER = Logger.getLogger(TestOOM.class.getName());

    public static void main(String[] args) throws IOException {
        BufferedReader rdr = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
        LOGGER.info("Press Enter to make OOM...");
        rdr.readLine();
        StringBuilder stringBuilder = new StringBuilder();
        try {
            while (true) {
                stringBuilder.append("foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobar");
            }
        } catch (Throwable thr) {
            LOGGER.log(Level.SEVERE, "Here is a some Throwable, printing it and ignoring.", thr);
        }
        LOGGER.info("I am still alive! Press Enter to quit...");
        rdr.readLine();
    }
}
Нет, класс вполне обычный, я просто скрыл содержимое стектрейса, а в качестве номеров строк указал сие магическое число, это просто отсылка к мему "Стопицот".
Я даже сомневаюсь, что во всём проекте столько строк наберётся.
Более правильным вариантом будет всё же натравить тот же Zabbix, например, на слежение за логфайлом, в который пишется OOM, чтобы он сигнализировал как-то об этом событии, и админы уже могли и дампы снять, и перевалить приложение. Плюс никто не запрещает автоматизировать процесс, мне кажется.
Вдобавок можно также следить за какими-то критическими вещами, типа слова Abandoned в том-же логе.
Отвечаю, что использовать не пробовали, но спасибо, что подсказали, когда появится время — надо бы посмотреть, что он из себя представляет.
Скажу лишь, что под капотом DBCP 2.0 уже располагается commons-pool2, это было причиной переименования параметров.
В pom'нике в ветке trunk проекта commons-dbcp2 сейчас наблюдается строчка
<commons.pool.version>2.3</commons.pool.version>
Если прогуляться в класс http://svn.apache.org/viewvc/commons/proper/pool/tags/POOL_2_3/src/main/java/org/apache/commons/pool2/impl/GenericObjectPool.java?view=markup, то в строке 1132 можно увидеть строчку
private final LinkedBlockingDeque<PooledObject<T>> idleObjects;
Ну и в методе «public T borrowObject(long borrowMaxWaitMillis)» (строка 411) эта очередь активно используется.
Думаю, что DBCP 2 должен быть быстрее, чем 1.4, и у меня даже есть желание перейти на DBCP 2+.
Надо бы посмотреть содержимое и попробовать провести бенчмарк, который предоставляет разработчик HikariCP, чтобы понять, каков этот коэффициент ускорения.
По предоставленной Вами ссылке так и написано в первых двух пунктах, что мол «Note that this does not apply to Commons DBCP 2.x.».
Сначала отвечу на Ваш вопрос:
Начну, пожалуй, с примеров кода...
Тестовый класс
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class TestOOM {
    public static void main(String[] args) throws IOException {
        BufferedReader rdr = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
        System.out.println("Press Enter to make OOM...");
        rdr.readLine();
        StringBuilder stringBuilder = new StringBuilder();
        while (true) {
            stringBuilder.append("foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobar");
        }
    }
}
Запускаем это дело
$ ls
TestOOM.class

$ java -Xmx256m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=. TestOOM
Press Enter to make OOM…

java.lang.OutOfMemoryError: Java heap space
Dumping heap to ./java_pid15967.hprof…
Heap dump file created [85330696 bytes in 0,401 secs]
Exception in thread «main» java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2367)
at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:130)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:114)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:415)
at java.lang.StringBuilder.append(StringBuilder.java:132)
at TestOOM.main(TestOOM.java:16)
В примере выше я указал -Xmx256m, чтобы оно не генерировало дамп памяти на 5 гиг.
В результате в папке, в которой я запускал «приложение», рядом с класс-файлом появился файл java_pid15967.hprof.
В качестве рекомендаций могу посоветовать проверить, что перед параметром HeapDumpOnOutOfMemoryError стоит знак плюс, "-XX:+HeapDumpOnOutOfMemoryError", если будет минус ("-XX:-HeapDumpOnOutOfMemoryError"), то это наоборот, «выключить» (надо, кстати, об этом ещё кое-куда написать, а то чувствую, насоветовал я там человеку...).
К тому же, если есть возможность «подключиться» к процессу, который запущен, с помощью JVVM, то там будет видно, включена ли опция, на вкладке «Overview» будет чёрным по серому написано «Heap dump on OOME: enabled».
Вот, как-то так обстоят дела.
Дамп памяти «наживую» создать при этом невозможно

Ну, может помочь ключ -F для jmap ;) http://docs.oracle.com/javase/7/docs/technotes/tools/share/jmap.html
В этом случае игнорируется параметр live.
Пожалуйста, я буду рад, если поможет.
Если я правильно разобрался в проблемной области, то jmap требуется запускать от того же пользователя, под которым запущено приложение. Отсюда танцы с бубном вокруг PsExec под виндой, ведь томкет в ней запускается от системы в случае, если устанавливался как служба.
Да, jmap не связан никак с опцей автоматической генерации дампа.
Внёс корректировку,
BaseMatcher<byte[]> arrayStartingWithA
вместо простого
BaseMatcher arrayStartingWithA
Это позволило убрать (byte[]) перед argThat, и теперь строчка выглядит так:
.write(argThat(arrayStartingWithA), eq(0), eq(1));
zavg Статья отличная спасибо.
А я оставлю для интересующихся вот эту ссылку: en.wikipedia.org/wiki/Server_Name_Indication
Здесь описано, что было добавлено в TSL, чтобы стала возможной ситуация «каждый домен на одном и том же IP-адресе использует свой собственный сертификат».
Узнал про эту технологию, когда бодался, почему у меня подхватывается не так строится цепочка сертификатов в Java 1.6 при обращении к подобному мультихост-домену. Выяснилось, что поддержка SNI была добавлена лишь начиная с версии Java 1.7.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность