Задать вопрос
  • Как настроить Maven на копирование во время сборки?

    Vamp
    @Vamp
    Это делается при помощи плагинов. Вот на выбор antrun и maven-resources-plugin:
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <configuration>
                            <tasks>
                                <copy todir="${project.basedir}/target/jfx/speedmap">
                                    <fileset dir="/home/fluent/mapGr"/>
                                </copy>
                            </tasks>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
    
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.0.1</version>
                <executions>
                    <execution>
                        <id>copy-resources-foreign</id>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.basedir}/target/jfx/speedmap</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>/home/fluent/mapGr</directory>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>


    Есть директории, лежащие вне Java -проекта. Это не ресурсы (их надо копировать в директорию, отличную от target\classes).

    В вашем случае это всё-таки ресурсы. Просто по умолчанию maven считает ресурсами только контент из директорий src/main/resources и src/test/resources. Вам просто нужно сказать где ещё располагаются ресурсы, необходимые для сборки проекта.

    Вообще говоря, не очень хорошо завязываться на внешние по отношению к проекту ресурсы. Это усложняет вхождение новых участников, так как теперь уже недостаточно просто запустить mvn install и получить готовый артефакт. Да и сами потом забудете/запутаетесь, будете тратить время на вспоминание как правильно собирать проект. Хотя, конечно, хозяин - барин.
    Ответ написан
    1 комментарий
  • Можно ли в Java 8 устанавливать лимит памяти исходя из системной памяти, а не памяти java процесса?

    Vamp
    @Vamp
    В вашем случае решения чисто на java нет. Здесь необходимо зарядить регулярную задачу (cron), которая будет смотреть свободную физическую память в системе и убивать самое толстое java приложение при достижении 95% лимита памяти. Например, так:
    #!/usr/bin/env bash
    
    # pid'ы отслеживаемых java процессов
    # задачку определения актуальных pid'ов оставлю на вас
    PID1=1234
    PID2=5678
    
    # минимальное допустимое количество свободной памяти в процентах
    MIN_MEM_SIZE=5
    
    function get_java_mem {
      jstat -gc $1 | awk 'NR==1 {print ($3 + $4 + $6 + $8 + $10)}'
    }
    
    function get_free_mem {
      free | awk 'NR==2 {print ($7 * 100) / $2}'
    }
    
    if [ $(echo "`get_free_mem` < $MIN_MEM_SIZE" | bc) -eq "1" ]; then
      if [ $(echo "`get_java_mem $PID1` > `get_java_mem $PID2`" | bc) -eq "1" ]; then
        PID_TO_KILL=$PID1;
      else
        PID_TO_KILL=$PID2
      fi
      echo "Memory shortage detected. Taking heap dump and killing process $PID_TO_KILL"
      jmap  -dump:format=b,file=${PID_TO_KILL}.heapdump.bin $PID_TO_KILL
      kill $PID_TO_KILL
    fi


    если я пропишу -Xmx2g то оба влезут, но если один процесс использует все 2 гб, то второй не может эту память использовать.

    Не очень ясно зачем нужны такие качели. Если приложение нормально работает с -Xmx2g, то с -Xmx4g сильно лучше не станет. Разве что full gc будет происходить немного чаще, только и всего.
    Ответ написан
    Комментировать
  • Как красиво завершить работу с NIO при прерывании потока?

    Vamp
    @Vamp Автор вопроса
    Проблема оказалась в изначально неверном предположении.

    Во всех книгах написано, что jvm завершает свою работу только после завершения всех не daemon потоков. Но нигде не уточняется при каких условиях поток получает interrupted status. Мне всегда казалось, что при закрытии приложения внешним образом (Crtl+C, SIGTERM, рестарт системы), jvm сначала установит interrupted статус всем потокам, дождётся завершения последнего не daemon потока, после чего закроется. И достаточно просто продумать адекватную реакцию на прерывание потока.

    Как оказалось, единственный способ установить interrupted status - вызвать Thread.interrupt() из пользовательского кода. А все остальные способы завершения тупо останавливают потоки jvm без возможности как-то отреагировать на ситуацию. И единственный способ отследить это - установить shutdown hook.
    В принципе, это решение меня вполне устраивает.
    Ответ написан
    Комментировать
  • В какой ситуации я получаю writable SelectorKey из nio Selektor'a в Java?

    Vamp
    @Vamp
    Writable получается всегда, когда есть свободное место в output буфере у какого-либо сокета.

    Технически, метод write() всего лишь записывает данные в специальный буфер в памяти, привязанный к сетевому сокету. Размер этого буфера регулируется опцией SO_SNDBUF. Это in-memory операция. Реальная работа с сетью на этом этапе не происходит.

    Данные из буфера в сеть отправляются уже непосредственно операционной системой. Скорость опустошения буфера зависит от разных факторов, в частности, пропускной способности сети и производительности машины на другом конце провода. Если в буфере есть хотя бы один свободный байт, то флаг OP_WRITE будет установлен.

    На OP_WRITE нужно подписываться только когда есть данные, которые можно отправить удаленной стороне и отписываться сразу, как только вся порция данных будет записана в сокет. В противном случае, в результате каждого вызова Selector.select() вы будете получать список всех сокетов, у которых есть свободное место в буфере. А так как данных для записи у вас нет - только впустую потратите ресурс процессора.

    Образно говоря, на OP_READ вы подписываетесь, когда хотите послушать что говорят другие, а на OP_WRITE, когда вам самим есть что сказать.
    Ответ написан
    Комментировать