All streams
Search
Write a publication
Pull to refresh
14
0
Сергей Б. @sergey-b

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

Send message
Вот, пожалуйста. Выгружаю JDBC-драйвер, загруженный из отдельного каталога. Пока он не выгружен, каталог в Windows не удаляется, так как файлы заняты. В семерке все удаляется сразу, а в восьмерке только после удара в бубен через JMX.

unload()
public void unload() {
    try {
        if (driverManager != null) {
            DriverManagerProxy dmp = driverManager;
            this.driverManager = null;
            dmp.deregisterDriver(driver);
        } else {
            DriverManager.deregisterDriver(driver);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
    this.driver = null;
    if (classLoader != null) {
        ResourceBundle.clearCache(classLoader);
        try {
            cleanupThreadLocals(this.classLoader);
        } catch (ReflectiveOperationException e1) {
            e1.printStackTrace();
        }
        try {
            this.classLoader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.classLoader = null;
        System.gc();
        System.runFinalization();
        System.gc();
        System.runFinalization();
    }
    if (!delete(dir, false)) {
        dumpHeap();
        delete(dir, false);
    }
}

У них свой JRE, не HotsSpot, которым пользовался автор поста.
Очень простые. Я проверял, как работает мой метод finalize(). В 7-й яве он у меня вызывался после System.gc(). В 8-й яве уже не вызывался. Специальных настроек GC я не включал намеренно, потому что интересовало именно поведение JVM по умолчанию. Тогда я заменил System.gc() на сброс дампа, и finalize() отработал во всех версиях явы.
И правда. Оказывается в Eclipse, с которым я работаю, в конфиге прописаны параметры

-XX:+UseG1GC
-XX:+UseStringDeduplication
Действительно. Не обратил внимания.
Сейчас вот такую. Эксперименты ставил на более ранней версии восьмерки.

java version «1.8.0_102»
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
Весь оверхед связан с необходимостью автоматической сборки мусора. Если ваши алгоритмы предполагают наличие 100 млн объектов с возможностью произвольного доступа, то имеет смысл задуматься о самостоятельном управлении памятью, которую они занимают. Все эти объекты должны существовать вместе и уничтожаться будут тоже все разом, поэтому нет необходимости гонять сборщик мусора над ними. Поэтому заведите большой массив с данными и обертку, которая их вынимает по различным запросам.
А в восьмерке разве не G1 по умолчанию?
В 8-й яве System.gc() никаких видимых изменений в куче не производит. По крайней мере в тех экспериментах, которые я сам проводил. Единственный надежный способ выполнить полную сборку мусора — это сделать дамп кучи только с живыми объектами.
Мне кажется, что проще использовать возможности binfmt и запускать jar-ы как обычные исполняемые файлы.
Должен заметить, что SimpleDateFormat непотокобезопасный от слова «совсем».
Да, зависит. А также зависит от соотношения количества операций вставки со всеми остальными операциями. Но вывод о том, что ArrayList или ArrayDeque всегда лучше LinkedList, все равно остается неверным. Именно с этим выводом, сделанным в статье, я не согласен. Нетрудно подобрать такие параметры коллекции и варианты использования, при которых LinkedList будет работать лучше.

Кстати, хорошая идея — реализовать LinkedList на массиве. Надо будет при случае попробовать.
ArrayList, хотя и тратит меньше памяти, чем LinkedList, но требует, чтобы память была выделена одним целым куском, а это более дорогой ресурс.

Если есть необходимость вставки в середину, то надо использовать LinkedList, и то, что эта задача названа экзотической, ничего не меняет.
Так и есть. Java 7.

Тогда вобщем-то понятно из-за чего происходило торможение. GC останавливает поток, работающий в synchronized-методе, а за ним останавливаются и многие другие потоки на входе в этот метод. В результате получается, что каждая малая сборка работает как stop-the-world.
Понятно.

А правильно ли я понимаю, что G1 во время малой сборки приостанавливает отдельные потоки?
Размер кучи был 6 Гб. gc.log в наличии. Подскажите, что в нем посмотреть?

Меня вот такие записи смутили

[Full GC 2171M->671M(6144M), 4.1407616 secs]
[Eden: 290.0M(496.0M)->0.0B(814.0M) Survivors: 40.0M->0.0B Heap: 2171.3M(6144.0M)->671.9M(6144.0M)], [Perm: 524287K->252914K
(253952K)]
[Times: user=5.05 sys=0.42, real=4.13 secs]
Размер кучи 10 Гб. 24 логических ядра на виртуальной машине, если память мне не изменяет.
По пропускной способности. Времена отклика тоже были хуже, и, что самое неприятное, были нестабильны.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Works in
Registered
Activity