Каковы будут последствия, если мы попытаемся постоянно подключить собственный поток к DVM (JVM)? - PullRequest
11 голосов
/ 20 декабря 2011

Возможно ли постоянное присоединение собственного потока к JVM (AttachCurrentThread) (или), лучше ли его присоединять при необходимости (вызов функций java) и немедленно отсоединять, как только работа завершена

Я написал пример нативного приложения с вышеописанными случаями, не нашел никакой разницы. Но, прибегая к помощи Google, я смутно узнал, что при подключении к JVM планирование потоков JVM отвечает за планирование, иначе ОС будет планировать собственный поток (если он не подключен). Это правда?

Важно отсоединить любую нить, которая была ранее присоединена; в противном случае программа не завершится при вызове DestroyJavaVM. - http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniref.html#attach

Будут ли проблемы с производительностью?
Пожалуйста, дайте мне знать, если кто-нибудь знает, это один из моих важных аспектов дизайна.

Спасибо и С уважением.

Ответы [ 3 ]

4 голосов
/ 26 января 2012

Вообще говоря, основной ценой производительности является создание потока на уровне ОС.Либо поток создается изначально, а затем присоединяется или напрямую создается как java.lang.Thread из Java API.

Если вы повторно используете тот же собственный поток, производительность будет хорошей.Кстати, не создавайте десятки собственных потоков.

JVM не планирует сами потоки .Это может привести их в состояние сна по разным причинам, таким как сборка мусора.В этом конкретном случае он должен ждать вызова JNI из собственного потока перед сбором.Таким образом, вы должны избегать слишком длинного выполнения кода без вызова JNI, чтобы поддерживать низкое потребление кучи виртуальной машины.

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

1 голос
/ 25 октября 2012

Когда собственный поток прикреплен постоянно, он не может выйти из собственного потока.Его сбой, когда мы пытаемся выйти из нативного потока без отсоединения.Но когда мы отсоединились, родная нить смогла сделать изящный выход.

0 голосов
/ 09 февраля 2016

У меня не было никаких последствий, кроме повышения производительности.

Это именно то, что я делаю в приложении, которое перетасовывает данные ByteBuffer с прямым распределением между двумя уровнями.Я обнаружил, что стоимость постоянного присоединения / отсоединения была очень высокой, как и следовало ожидать.Мой подход заключается в запуске одного управляемого Java-потока, который при запуске выполняет блокирующий вызов JNI, который на уровне C / C ++ содержит цикл условие / стиль сигнала (чтобы не потреблять циклы ЦП).Затем я могу сигнализировать о цикле в любое время, когда данные готовы к обработке, и, наоборот, я могу сигнализировать до Java, когда тяжелая работа завершена.

new Thread(() -> myBlockingJNICall()).start();

Затем вниз на уровне C:

#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus

    static JavaVM *jvm = nullptr; // captures the JVM on load

    JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *the_jvm, void* /*reserved*/)
    {
        jvm = the_jvm;
        return JNI_VERSION_1_2; // must export 1_2 to use any of the new functions, 1_1 otherwise
    }

    JNIEXPORT jboolean JNICALL Java_myBlockingJNICall(JNIEnv *env, jobject)
    {
       // loop forever waiting for work and using env for signalling
       // jvm is stored in case we need to manually attach (or perform more complex work requiring jvm access)
       return JNI_TRUE;
    }

#ifdef __cplusplus
}
#endif // __cplusplus
...