Android 技术: 追踪vm 如何调用基础类

Android 启动的时候创建第一个 vm 程序 zygote, 而后用它孵化所有的 vm 进程( 就是 java 进程), 这是因为 vm 比较吃内存, 用孵化的方法可以共享内存, 尤其是代码段. 而Linux的内存管理是 copy on write, 所以 fork 使得内存共享得以实现


虚拟机 vm 就是一个 runtime,  解释 byte 并运行而已.  loadloader 负责吧clas装载到内存中, 而且vm 可以注册本地函数, 而后用 native call 调用执行, 这个机制就是 JNI

当你运行一个vm的时候, 发现有如此多的 java 基础类可以调用, 而通过设定 class path 又可以调用更多的类库, 是否很神奇


通过分析 harmony 的一段代码,  探究vm 如何调用基础类

harmony 是一个开源的项目, 目标是替换掉 sun 提供的基础类(为了让java 脱离 sun (现在是 Oracle) 的控制)


我们运行java的时候,调用 System 那么他们是如何附着到 VM 上的.

察看: System.java
static {
         ...
        out = new String.ConsolePrintStream(new BufferedOutputStream(new FileOutputStream(
                FileDescriptor.out)));
        in = new BufferedInputStream(new FileInputStream(FileDescriptor.in));
        ...
    }

可以看看其调用了 FileInputStream
察看: FileInputStream.java
 private IFileSystem fileSystem = Platform.getFileSystem();
调用了 Platform

察看:  Platform.java
static final IMemorySystem MEMORY_SYSTEM = OSMemory.getOSMemory();
调用OSMemory

察看: OSMemory.java
    public native long malloc(long length) throws OutOfMemoryError;
    public native void free(long address);

再找到 OSMemory.c 如下
    这下真相大白了, 原来 基本类库 也是用 JNI 的方法实现的, 就是说调用关系是 java -> java 基础类-> jni

    那么可以预测 图形库, sockets 等也都是JNI来实现的了

JNIEXPORT jlong JNICALL Java_org_apache_harmony_luni_platform_OSMemory_malloc
  (JNIEnv * env, jobject thiz, jlong size)
{
  PORT_ACCESS_FROM_ENV (env);

  void *address = hymem_allocate_memory ((UDATA) size);

  if (address == NULL)
    {
      throwNewOutOfMemoryError(env, "Insufficient memory available.");
    }

  return (jlong) ((IDATA) address);
}

JNIEXPORT void JNICALL Java_org_apache_harmony_luni_platform_OSMemory_free
  (JNIEnv * env, jobject thiz, jlong address)
{
  PORT_ACCESS_FROM_ENV (env);

  hymem_free_memory ((void *) ((IDATA) address));
}


你可能感兴趣的:(android,VM)