JVM created via JNI in Delphi creates multiple threads

若如初见. 提交于 2019-12-11 13:19:23

问题


I have a problem with the JNI and delphi.

Whenever I create a JVM in delphi with this code:

  FillChar(Options, SizeOf(Options), #0);
  Options[0].optionString := '-Djava.class.path=' + 'blabla.jar';
  VM_args.version := JNI_VERSION_1_2;
  VM_args.options := @Options;
  VM_args.nOptions := 1;

  JVM := TJavaVM.Create(JNI_VERSION_1_6, getJvmPath());
  Errorcode := JVM.LoadVM(VM_args);

I try to close the JVM with this code, but only 1 thread get closed:

  JNIEnv.Free;
  JNIEnv := nil;

  JVM.JavaVM^.DetachCurrentThread(JVM.JavaVM);
  JVM.JavaVM^.DestroyJavaVM(JVM.JavaVM);
  UnloadJVM;

  JVM.Free;
  JVM := nil;

My application creates 4-6 threads, the threads are created at the last line of code here.

I tried to use DetachCurrentThread(), DestroyJavaVM() and UnloadJVM to resolve this issue, but then only 1 thread disappears max.

Is there a way to get rid of those threads?

Thanks in advance!


回答1:


According to Java JNI documentation, Chapter 5 - The Invocation API:

Unloading the VM

The JNI_DestroyJavaVM() function unloads a Java VM.

As of JDK/JRE 1.1, only the main thread could unload the VM, by calling DestroyJavaVM. As of JDK/JRE 1.2, the restriction was removed, and any thread may call DestroyJavaVM to unload the VM.

The VM waits until the current thread is the only non-daemon user thread before it actually unloads.

User threads include both Java threads and attached native threads.

This restriction exists because a Java thread or attached native thread may be holding system resources, such as locks, windows, and so on. The VM cannot automatically free these resources.

By restricting the current thread to be the only running thread when the VM is unloaded, the burden of releasing system resources held by arbitrary threads is on the programmer.

The VM will not automatically finalize your threads, and it will not completely unload until they terminate.

It is your responsability that your own threads get finished, but I guess that the extra threads that you are referring are created by the JVM itself when loaded.

Also note that the JNI documentation is somewhat ambiguous:

DestroyJavaVM

Unloads a Java VM and reclaims its resources.

The support for DestroyJavaVM was not complete in JDK/JRE 1.1. As of JDK/JRE 1.1 Only the main thread may call DestroyJavaVM.

Since JDK/JRE 1.2, any thread, whether attached or not, can call this function. If the current thread is attached, the VM waits until the current thread is the only non-daemon user-level Java thread. If the current thread is not attached, the VM attaches the current thread and then waits until the current thread is the only non-daemon user-level thread.

The JDK/JRE still does not support VM unloading, however.

So it seems that anyway the JVM is not completely unloaded until the program exits.



来源:https://stackoverflow.com/questions/24755926/jvm-created-via-jni-in-delphi-creates-multiple-threads

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!