我想在c++中用jni呼叫java程式的入口main函數,但是這樣建立的jvm比直接用javaw指令運行要卡很多,但是jvm參數設定的都是一樣的。在c++中運行,fps只有10-30,直接運行jar卻能達到50-100。
求教這是什麼原因?有什麼改進的辦法嗎?
#include <jni.h>
using namespace std;
extern "C" {
__declspec(dllexport) DWORD NvOptimusEnablement = 1;
}
int main() {
JavaVMOption options[7];
JNIEnv *env;
JavaVM *jvm;
JavaVMInitArgs vm_args;
long status;
jclass cls;
jmethodID mid;
options[0].optionString = "-XX:+UseG1GC";
options[1].optionString = "-XX:-UseAdaptiveSizePolicy";
options[2].optionString = "-XX:-OmitStackTraceInFastThrow";
options[3].optionString = "-Xmn512m";
options[4].optionString = "-Xmx2048m";
options[5].optionString = "-Djava.library.path=natives";
options[6].optionString = "-Djava.class.path=.;libraries.zip;main.jar";
std::memset(&vm_args, 0, sizeof(vm_args));
vm_args.version = JNI_VERSION_1_8;
vm_args.nOptions = 7;
vm_args.options = options;
cout << "start creat jvm!\n";
status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if (status != JNI_ERR) {
cout << "jvm created success\n";
cls = env->FindClass("main/Main");
if (cls != 0) {
mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
if (mid != 0) {
jclass clz_string = env->FindClass("java/lang/String");
if (clz_string != NULL) {
jobjectArray result = env->NewObjectArray(2, clz_string, NULL);
jstring arg0 = env->NewStringUTF("--accessToken");
jstring arg1 = env->NewStringUTF("14233482b8dbad97617757a5c31d5872");
env->SetObjectArrayElement(result, 0, arg0);
env->SetObjectArrayElement(result, 1, arg1);
env->CallStaticVoidMethod(cls, mid, result);
}
}
} else {
cout << "class not found\n";
}
jvm->DestroyJavaVM();
return 0;
} else {
return -1;
}
}
伊谢尔伦2017-05-16 13:23:53
你看過jdk源碼中javaw.exe的源碼就知道了,它也是用JNI_CreateJavaVM
實現的,所以可以對比下你的程式碼跟javaw.exe實現的有什麼不同。
另外想到兩種可能:
Windows下jvm有server
和client
两种类型,性能差别还是挺大的,javaw.exe
会自动选择(也可以用-server
或-client
指定),用c++呼叫好像要指定用哪個jvm.dll的;
c++編譯時用了哪個標準函式庫(單執行緒還是多執行緒),不清楚是否會影響到jvm的呼叫。