extern关键字有两个用处:

(1)extern在C/C++语言中表示函数和全局变量作用范围(可见性)的关键字,这个关键字会告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。

(2)在C++中引用C语言中的函数和变量,在包含C语言头文件时,需要使用extern "C"来处理。

1、extern表示函数和变量作用范围

HotSpot VM是一个由多文件组成的复杂系统,文件与文件之间难免会共享一些变量和函数,怎么办呢?例如在类加载时,为了处理并发问题会在多个文件中用到SystemDictionary_lock锁,这个锁在mutexLocker.hpp文件中被声明为外部变量,如下:

extern Monitor* SystemDictionary_lock;

文件中用extern对SystemDictionary_lock做“外部变量声明”,在mutexLocker.cpp中定义了这个外部变量。在编译和连接时,系统会由此知道SystemDictionary_lock是一个已在别处定义的外部变量,并将在另一个文件中定义的外部变量的作用域扩展到本文件,在本文件中可以合法地引用外部变量SystemDictionary_lock。

2、兼容性处理

extern "C"在HotSpot VM中使用的比较多,如jni.h,如果你编写过native方法,那么这个头文件你应该熟悉,当写native方法的C或C++实现时,通常会引入这个头文件,这样我们就能在我们自己编写的函数中和虚拟机交互了。

可以借助javah工具生成我们需要的头文件,例如如下实例:

#include <jni.h>

#ifndef _Included_com_mprofiler_Test
#define _Included_com_mprofiler_Test #ifdef __cplusplus
extern "C" {
#endif JNIEXPORT void JNICALL Java_com_mprofiler_Test_helloWorld
(JNIEnv *, jobject, jstring); #ifdef __cplusplus
}
#endif #endif
  

已经自动为我们引入了jni.h头文件。其中的宏__cplusplus是为了避免在C++中使用C语言。这样我们即可以通过C语言实现自己的native方法,也可以用C++实现自己的native方法。在jni.h头文件中同样有__cplusplus判断,也是为了支持用C或C++写native方法,不过由于C语言没有对象的概念,所以两者写起来还是有一些区别的,例如调用某个JNI函数,C语言写法:

(*env) -> GetStringUTFChars(env, str, NULL);

C++的写法如下:

env->GetStringUTFChars(jstr, nullptr);

另外还需要提示一点的是,通过如上的操作后,编译器会保持原本的名称。如果是C++函数,在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称。例如Launcher在启动HotSpot VM时,通常会通过dlsym()函数查找符号,如下:

ifn->CreateJavaVM = (CreateJavaVM_t)
dlsym(libjvm, "JNI_CreateJavaVM");

这个JNI_CreateJavaVM就是通过extern "C"来保证函数本名的, 如果不使用,那么dlsym()可能无法在动态链接库libjvm.so中通过函数名找到这个函数。

还比如Async Profiler为了异步获取线程栈,要调用HotSpot VM内部的AsyncGetCallTrace()函数,由于这个函数有extern "C",所以使用函数本名查找即可。如果是C++,那么由于Name Mangling的存在,需要确定Name Mangling后的函数名称,如Async Profiler通过TLAB内部的函数统计分配速率时,用了_ZN11AllocTracer27send_allocation_in_new_tlab这样的函数名称。

本人最近准备出一个手写Hotspot VM的课程,超级硬核,从0开始写HotSpot VM,将HotSpot VM所有核心的实现全部走一遍,如感兴趣,加我速速入群。

群里可讨论虚拟机和Java性能剖析与故障诊断等话题,欢迎加入。

 

C++的extern关键字在HotSpot VM中的重要应用的更多相关文章

  1. JVM详解之:HotSpot VM中的Intrinsic methods

    目录 简介 什么是Intrinsic Methods 内置方法的特点 多样性 兼容性 java语义的扩展 Hotspot VM中的内置方法 intrinsic方法和内联方法 intrinsic方法的实 ...

  2. HotSpot VM 中的JIT分类

    在HotSpot VM中内嵌有两个JIT编译器,分别为Client Compiler和Server Compiler,但大多数情况下我们简称为C1编译器和C2编译器.开发人员可以通过如下命令显式指定J ...

  3. 转:什么是即时编译(JIT)!?OpenJDK HotSpot VM剖析

    重点 应用程序可以选择一个适当的即时编译器来进行接近机器级的性能优化. 分层编译由五层编译构成. 分层编译提供了极好的启动性能,并指导编译的下一层编译器提供高性能优化. 提供即时编译相关诊断信息的JV ...

  4. HotSpot VM运行时

    HotSpot VM运行时系统为HotSpot JIT编译器和垃圾收集器提供服务和通用API,同时还为VM提供启动.线程管理.JNI(Java本地接口)等基本功能.HotSpot VM运行时环境担当许 ...

  5. 【转载】C/C++中extern关键字详解

    1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...

  6. C++中extern关键字用法小结

    总结C++中关于extern关键字的用法. 1.变量的生明和定义中 C++语言支持分离式编译机制,该机制允许将程序分割为若干个文件,每个文件可被独立编译.为了将程序分为许多文件,则需要在文件中共享代码 ...

  7. C/C++中extern关键字解析

    1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...

  8. C语言中的 extern 关键字

    今天在 BLE 中看到很多 extern 关键字,现在总结一下: extern 关键字主要用于在一个c文件中要用到另一个c文件中的变量或者函数. example: #extern_base.c ; # ...

  9. C/C++中extern关键字详解

    转自:http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html 1 基本解释:extern可以置于变量或者函数前,以标示变 ...

  10. 转载 浅谈C/C++中的static和extern关键字

    浅谈C/C++中的static和extern关键字 2011-04-21 16:57 海子 博客园 字号:T | T   static是C++中常用的修饰符,它被用来控制变量的存贮方式和可见性.ext ...

随机推荐

  1. harbor 搭建和部署

    Docker官方的Docker Registry镜像,可以用来储存和分发Docker镜像.不过实在不昨的,仅仅能储存和分发镜像,也不提供UI,你还得自己找一个过时的UI搭建,受限制于Docker Re ...

  2. 深度学习(四)——torchvision中数据集的使用

    一. 科研数据集 下载链接: https://pytorch.org/vision/stable/index.html 本文中我们使用的是\(CIFAR\)数据集 二.CIFAR10数据集详解 具体网 ...

  3. subprocess Python执行系统命令最优选模块

    简介 subprocess 是 Python 中执行操作系统级别的命令的模块,所谓系级级别的命令就是如ls /etc/user ifconfig 等和操作系统有关的命令. subprocess 创建子 ...

  4. 简单了解下最近正火的SwissTable

    去年看到字节跳动给golang提了issue建议把map的底层实现改成SwissTable的时候,我就有想写这篇博客了,不过因为种种原因一直拖着. 直到最近遇golang官方开始讨论为了是否要接受Sw ...

  5. Java通用返回工具类Result

    通用返回类Result 前言:Java项目搭建时,常常需要去封装一个通用型的Result工具类,下面就是我自己封装的常用的返回类,可以直接使用.(有部分Swagger注解,使用时可忽略) 第一步.创建 ...

  6. 与AI对话 -- 20230221 -- linux 性能分析相关的软件包

    linux 性能分析相关的软件包有哪些,各自包含了哪些命令 sysstat:sysstat 包含了丰富的监控系统性能的工具,例如 sar(系统性能分析器).iostat(设备 IO 状态分析器).mp ...

  7. GIT保存记录原理之commit对象

    GIT 中提交对象非常的重要,我们通过它记录代码提交过程.进行文件保存.回退等操作,那么它是怎样帮助我们记录这些信息的呢?其实就是都保存在项目根目录的 .git 文件夹中. 新建空项目 ```gitD ...

  8. [linux]常见内核TCP参数描述与配置

    前言 所有的TCP/IP参数都位于/proc/sys/net目录下(请注意,对/proc/sys/net目录下内容的修改都是临时的,任何修改在系统重启后都会丢失),如果需要固化设置,则需要修改/etc ...

  9. 三维模型OSGB格式轻量化技术在大规模场景的加载和渲染的作用分析

    三维模型OSGB格式轻量化技术在大规模场景的加载和渲染的作用分析 在移动设备上,大规模场景的加载和渲染是一个不容忽视的问题.对于OSGB格式轻量化处理来说,大规模场景的加载和渲染也是其中一项重要的任务 ...

  10. C++ ASIO 实现异步套接字管理

    Boost ASIO(Asynchronous I/O)是一个用于异步I/O操作的C++库,该框架提供了一种方便的方式来处理网络通信.多线程编程和异步操作.特别适用于网络应用程序的开发,从基本的网络通 ...