乐趣区

关于jvm:C启动JVM

性能介绍

1. C++ 启动 Java 虚拟机

2. 通过 C ++ 指针调用 main 办法

环境

JDK: jdk-17.0.9
mingw-w64: x86_64-8.1.0-release-win32-seh-rt_v6-rev0

实现过程

1. 编写 cpp 程序

StartJVM.cpp

#include <jni.h>       // JNI header provided by JDK
#include <stdio.h>     // C Standard IO Header
#include <windows.h>

int main() {JavaVM *jvm;       // Pointer to the JVM (Java Virtual Machine)
    JNIEnv *env;       // Pointer to native interface

    // JVM initialization arguments
    JavaVMInitArgs vm_args;                         
    
    JavaVMOption* options = new JavaVMOption[3];

    options[0].optionString = (char*) "-Djava.class.path=D:/SDK/jdk-17.0.9/lib;."; // 设置你的类门路 (classpath),这里只是一个例子
    options[1].optionString = (char*) "-Xmn512m";
    options[2].optionString = (char*) "-Xmx1g";
    // options[3].optionString = (char*) "-Djava.library.path=D:/SDK/jdk-17.0.9/bin";
    vm_args.version = JNI_VERSION_10;             // JVM version. This indicates version 1.6
    vm_args.nOptions = 3;
    vm_args.options = options;
    vm_args.ignoreUnrecognized = JNI_TRUE;
    
    printf("JNI_CreateJavaVM %s\n", options[0].optionString);
    HINSTANCE hVM = LoadLibrary("D:\\SDK\\jdk-17.0.9\\bin\\server\\jvm.dll");
    if (hVM == NULL) {printf("Load failed..");
    }

    typedef jint (CALLBACK *fpCJV)(JavaVM**, void**, JavaVMInitArgs*);
    fpCJV CreateJavaVM = (fpCJV)GetProcAddress(hVM, "JNI_CreateJavaVM");
    jint rc = CreateJavaVM(&jvm, (void**)&env, &vm_args);

    // 加载并初始化一个 JVM,"jvm" 是返回的 JVM 接口的指针,"env" 是返回的 JNI 接口的指针
   
    //jint rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);  
    printf("JNI_CreateJavaVM Finished!\n");
    
    if (rc != JNI_OK) {if (rc == JNI_EVERSION) {fprintf(stderr, "FATAL ERROR: JVM is oudated and doesn't meet requirements");
        }
        else if (rc == JNI_ENOMEM) {fprintf(stderr, "FATAL ERROR: Not enough memory for JVM");
        }
        else if (rc == JNI_EINVAL) {fprintf(stderr, "FATAL ERROR: invalid ragument for launching JVM");
        }
        else if (rc == JNI_EEXIST) {fprintf(stderr, "FATAL ERROR: the process can only launch one JVM an not multiple");
        }
        else {fprintf(stderr, "FATAL ERROR:  unknown error");
        }
        return rc;
    }
    else {printf("JVM load succeeded. Version\n");
    }

    // 在这里你能够开始调用 Java 代码 ...
    printf("可用调用 Java 了 \n");

    /* invoke the Main.test method using the JNI */
    jclass cls = env->FindClass("JavaMain");
    jmethodID mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
    env->CallStaticVoidMethod(cls, mid, 100);

    // 敞开 JVM
    jvm->DestroyJavaVM();
    
    return 0;
}

JavaMain.java

public class JavaMain {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {System.out.println("I'm java");
    }
}

2. 编译

编译 cpp
g++ -Wall -g -I"D:\SDK\jdk-17.0.9\include" -I"D:\SDK\jdk-17.0.9\include\win32" -I"D:\SDK\jdk-17.0.9\include\win32\bridge" -L"D:\SDK\jdk-17.0.9\bin\server" -L"D:\SDK\jdk-17.0.9\bin" -L"D:\SDK\jdk-17.0.9\lib" -ljvm -fPIC StartJVM.cpp -o StartJVM.exe
参数阐明:
-I 指定.h 文件门路
-L 指定 dll 门路
-ljvm 加载 jvm.dll
-o 输入门路

将 JavaMain 也编译到 StartJVM.exe 同目录,最终成果

3. 执行 StartJVM.exe

双击执行即可

能够看到 JVM 加载胜利了,不过执行还有点故障。

退出移动版