У нас есть пакетное задание, которое считывает данные из базы данных и записывает их в файл. Работа написана поверх Spring Batch 2.8. Мы заметили, что он занимает много памяти и пытается ее настроить. У меня есть некоторые вопросы во время выполнения упражнения
Я знаю, что реализация finalize() не рекомендуется. В многочисленных сообщениях, которые я прочитал, они говорят, что объект может быть перенесен в ReferenceQueue, и поток Finalizer опросит очередь. Так есть способ, я могу проверить очередь себя? (Я знаю, что дамп памяти покажет это, но иногда файл слишком велик, чтобы перенести из живой системы на локальный компьютер и выполнить диагностику).
В чем же разница между тривиальным и нетривиальным методом finalize()? Не удалось найти статью, которая объясняет это.
Если метод finalize() не является хорошей идеей, почему AbstractPlainSocketImpl, FileInputStream и другие реализуют его? И как это, их метод финализации помогает им в GC и не быть частью недостижимого или мертвого кода?
При использовании jvisualvm или jmc - зафиксированный размер кучи отображается как 600 МБ. Но когда я выполняю команду ниже в нашей среде Linux, она показывает мне память как 800MB+.
ps --cols 500 -C java -o user,ppid,pid,pcpu,rss,size,vsize,cmd | grep <uid> | awk '{ print $3,$4,$5/1024}'
Сведения об окружающей среде
Number of cores: 2
OS: Red Hat Enterprise Linux Server release 6.5
Total Physical Memory: 7.69GB
JVM: Java HotSpot(TM) 64-Bit Server VM (24.45-b08) for linux-amd64 JRE (1.7.0_45-b18)
JVM Command Line Arguments: -Xloggc:../logs/Job-gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -XX:-PrintTenuringDistribution -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=5M -XX:-CITime -XX:-PrintClassHistogram -XX:-PrintConcurrentLocks -XX:-PrintAdaptiveSizePolicy -XX:-TraceClassLoading -XX:-TraceClassUnloading -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=7091 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=server.com
Garbage Collector used (this info is from JMC): ParallelScavenge for Young and ParallelOld for Old.
Я знаю, что дамп памяти покажет это, но иногда файл слишком велик для передачи из работающей системы на локальную машину и выполнения диагностики
Команда tar -czf dump.tar.gz dump.hprof
может помочь вам передать этот большой файл.
3 ГБ → 100 МБ.
Скорость сжатия файла дампа была бы такой большой.
java.lang.ref.Finalizer
не создается для каждого экземпляра (класса, который имеет тривиальный финализатор). Если класс определяет нетривиальный метод finalize, для каждого экземпляра этого класса создается экземплярjava.lang.ref.Finalizer
который напрямую ссылается класс java.lang.Finalizer (поддерживая экземпляр Finalizer живым). Смотрите это .finalze()
реализацияfinalze()
FileInputStream
иAbstractPlainSocketImpl
- это просто вызовы резервного копирования для очистки / закрытия открытых ресурсов на случай, если пользователь не сможет этого сделать. Обратите внимание, чтоfinalize()
никогда не может быть вызван. Этот код присутствует для обеспечения взаимодействия нижележащих потоков, чтобы у вас не было тупиков / блокировок.