最近把 csapp 的第七章链接看了一遍,发现之前虽然好几次都翻了这本书,却把这一章漏了。 在研究生实验室做的项目都是基于 C 语言,不过都是简单的寄存器读写,唯一有印象的是一段 DSP 的 sencond bootloader。

看到 Java 的 Object 和 Unsafe 中,有许多 native method,以前看 JDK 到此就截止了。 想起去年 JVM GC tune 时,煞有其事地跟了下 CMS GC 的源码,当时囫囵吞枣,现在完全不记得什么了,实在汗颜。 时间都用在哪儿了?决定现在跟着 hostspot 源码看下这些 native method 的实现。

首先需要了解怎么实现一个 native method。参考 链接 总结一下

  • create HelloJNI.java file
public class HelloJNI {
    static {
        // load libhello.so
        System.loadLibrary("hello");
    }

    public native void sayHello(String name, int times);

    public static void main(String[] args) {
        new HelloJNI().sayHello("liupeng", 3);
    }
}
  • generat HelloJNI.h for native method

javac HelloJNI.java && javah HelloJNI

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJNI */

#ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
    /*
     * Class:     HelloJNI
     * Method:    sayHello
     * Signature: (Ljava/lang/String;I)V
     */
    JNIEXPORT void JNICALL Java_HelloJNI_sayHello
        (JNIEnv *, jobject, jstring, jint);

#ifdef __cplusplus
}
#endif
#endif
  • create HelloJNI.c to impl C method
#include <jni.h>
#include <stdio.h>
#include "HelloJNI.h"

JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv * env, jobject thisObj, jstring name, jint times){
    // 由于 Java String 与 c string 内存表示不同,需要进行转换
    const char * c_name = (*env)->GetStringUTFChars(env, name, NULL);
    if (NULL == c_name)
        return;
    for (jint i = 0; i < times; i++) {
        printf("%s\n", name);
        printf("%s\n", c_name);
    }
}
  • compile HelloJNI.c to generate libhello.so

gcc -std=c99 -shared -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" HelloJNI.c -o libhello.so

生成 libhello.so 动态库. $JAVA_HOME/includejni.h 所在路径,$JAVA_HOME/include/linuxjni.h 所包含的 OS dependence

  • 至此可以运行 java -Djava.library.path=. HelloJNI, -Djava.library.path=. 指定 lib so 库所在路径。

Sytem.loadLibary(String libname) search path:

usr_paths = initializePath("java.library.path");
sys_paths = initializePath("sun.boot.library.path");

jvm.h 声明了 Object, System, Thread 等类的 native 方法


Compiler.java String jit = System.getProperty("java.compiler"); 制定 custom jit

jit 3 modes: int/mixed/comp

Øredev 2010 - JVM Bytecode for Dummies

The Java HotSpot Performance Engine Architecture

JVM 汇编指令