C++的extern关键字在HotSpot VM中的重要应用
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中的重要应用的更多相关文章
- JVM详解之:HotSpot VM中的Intrinsic methods
目录 简介 什么是Intrinsic Methods 内置方法的特点 多样性 兼容性 java语义的扩展 Hotspot VM中的内置方法 intrinsic方法和内联方法 intrinsic方法的实 ...
- HotSpot VM 中的JIT分类
在HotSpot VM中内嵌有两个JIT编译器,分别为Client Compiler和Server Compiler,但大多数情况下我们简称为C1编译器和C2编译器.开发人员可以通过如下命令显式指定J ...
- 转:什么是即时编译(JIT)!?OpenJDK HotSpot VM剖析
重点 应用程序可以选择一个适当的即时编译器来进行接近机器级的性能优化. 分层编译由五层编译构成. 分层编译提供了极好的启动性能,并指导编译的下一层编译器提供高性能优化. 提供即时编译相关诊断信息的JV ...
- HotSpot VM运行时
HotSpot VM运行时系统为HotSpot JIT编译器和垃圾收集器提供服务和通用API,同时还为VM提供启动.线程管理.JNI(Java本地接口)等基本功能.HotSpot VM运行时环境担当许 ...
- 【转载】C/C++中extern关键字详解
1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...
- C++中extern关键字用法小结
总结C++中关于extern关键字的用法. 1.变量的生明和定义中 C++语言支持分离式编译机制,该机制允许将程序分割为若干个文件,每个文件可被独立编译.为了将程序分为许多文件,则需要在文件中共享代码 ...
- C/C++中extern关键字解析
1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...
- C语言中的 extern 关键字
今天在 BLE 中看到很多 extern 关键字,现在总结一下: extern 关键字主要用于在一个c文件中要用到另一个c文件中的变量或者函数. example: #extern_base.c ; # ...
- C/C++中extern关键字详解
转自:http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html 1 基本解释:extern可以置于变量或者函数前,以标示变 ...
- 转载 浅谈C/C++中的static和extern关键字
浅谈C/C++中的static和extern关键字 2011-04-21 16:57 海子 博客园 字号:T | T static是C++中常用的修饰符,它被用来控制变量的存贮方式和可见性.ext ...
随机推荐
- WPF 入门笔记 - 03 - 样式基础及模板
程序的本质 - 数据结构 + 算法 本篇为学习李应保老师所著的<WPF专业编程指南>并搭配WPF开发圣经<WPF编程宝典第4版>以及痕迹大佬<WPF入门基础教程系列> ...
- AB实验:科学归因与增长的利器
第一章 AB实验的基本原理和应用 AB实验的相关概念: 3个基本参数:实验参与单元.实验控制参数.实验指标 2个核心价值:验证因果关系.量化策略效果 2个关键特性:先验性.并行性 基本流程:分流 -& ...
- ReactNative原理与核心知识点
React Native特点 跨平台 使用js写出页面组件代码被React框架统一转成Virtual DOM树,Virtual DOM树是UI结构的一层抽象,可以被转换成任何支持端的UI视图. Rea ...
- 01-面试必会-JAVA基础篇
1. Final 有什么用? 展开查看 被 final 修饰的类不可以被继承 被 final 修饰的方法不可以被重写 被 final 修饰的变量不可以被改变, 被 final 修饰不可变的是变量的引用 ...
- C# - ConcurrentDictionary 并发场景使用注意事项
1 自身作为 Enumerable 的遍历 自身作为可遍历对象,键值对为元素进行遍历,是线程安全的,但不提供快照,遍历过程中集合产生变更会直接反馈至此次遍历过程中.但并不一定能够保障获取数据的过程中, ...
- .Net下验证MongoDB 的 Linq 模式联合查询是否可用
MongoDB.Driver 类库提供了 Linq 查询的支持.然而,在使用 Linq 进行联合查询时,是否能够正确转换为 MongoDB 底层的查询语句还有待验证.今天,我将进行实验来验证一下. 输 ...
- hexo博客yilia主题_缺失模块_解决方案
hexo博客yilia主题,左侧栏目有一个全部文章的按钮,刚开始开始报错缺失模块,如下图: 我解决了这个问题着实不容易饶了弯路,但是跟着提示步骤,其实很简单,走起: 1.查看node版本 win键+R ...
- Android进阶-NDK技术
一.介绍 1.什么是ndk技术? 在学习ndk技术前,我们需要先了解一下JNI(Java Native Interface)技术,JNI技术是一种实现Java代码和C/C++代码之间交互的技术,它提供 ...
- go install 和 go get的区别
go install 和 go get 都是 Go 语言中的命令行工具,用于处理依赖关系和安装包.它们的主要区别在于功能和使用场景. go install: 功能:go install 命令用于编译并 ...
- MySQL的索引详解
在MySQL中,常见的索引类型有以下几种: B-Tree索引: B-Tree(Balanced Tree)索引是MySQL中最常见的索引类型.它基于B-Tree数据结构,适用于等值查询.范围查询和排序 ...