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. C# .NET CORE .NET6 RSA 公钥加密 私钥解密

    环境说明: .NET CORE 版本:.NET 6 . .NET CORE 对于RSA的支持: 1. .NET 6 中内置了对 PKCS1,PKCS8 2种私钥格式的支持. 2. 如果你要部署在Lin ...

  2. 【QCustomPlot】使用方法(源码方式)

    说明 使用 QCustomPlot 绘图库辅助开发时整理的学习笔记.同系列文章目录可见 <绘图库 QCustomPlot 学习笔记>目录.本篇介绍 QCustomPlot 的一种使用方法, ...

  3. 从隐私保护到AI隐私保护:隐私隐私保护的跨隐私保护治理框架实践案例

    目录 标题:<从隐私保护到AI隐私保护:跨隐私保护治理框架实践案例> 背景介绍 随着人工智能技术的广泛应用,隐私保护问题也日益突出.数据隐私泄露.算法歧视等问题引发了公众的担忧和不满.为了 ...

  4. Blazor前后端框架Known-V1.2.2

    V1.2.2 Known是基于C#和Blazor开发的前后端分离快速开发框架,开箱即用,跨平台,一处代码,多处运行. 概述 基于C#和Blazor实现的快速开发框架,前后端分离,开箱即用. 跨平台,单 ...

  5. 1、笔记本刷ubuntu,安装饥荒服务器

    目录 笔记本刷ubuntu,安装饥荒服务器 一.准备 二.笔记本刷机 1.制作Ubuntu server U盘启动盘 2.刷机 3.设置电源不休眠 三.安装饥荒服务器 四.最后说下网络 笔记本刷ubu ...

  6. 【SpringBoot】WebSocket在线聊天

    先看一下页面效果,有点简单粗暴!哈哈哈哈哈,别介意. 本文参考:SpringBoot2.0集成WebSocket,实现后台向前端推送信息 新建一个springboot项目 引入相关依赖 <dep ...

  7. Flutter 屏幕采集如何实现(提供示例demo)

    在视频会议.线上课堂.游戏直播等场景,屏幕共享是一个最常见的功能.屏幕共享就是对屏幕画面的实时共享,端到端主要有几个步骤:录屏采集.视频编码及封装.实时传输.视频解封装及解码.视频渲染.一般来说,实时 ...

  8. 【Azure API Management】实现在API Management服务中使用MI(管理标识 Managed Identity)访问启用防火墙的Storage Account

    问题描述 在Azure的同一数据中心,API Management访问启用了防火墙的Storage Account,并且把APIM的公网IP地址设置在白名单.但访问依旧是403 原因是: 存储帐户部署 ...

  9. 压制GIF做的一点点小尝试 以及ezgif的基本功能使用

    事情的起因 首先群友给我整了个loli莉音的视频 很可爱 但是用qq接收的视频没法一直在那边kawaii 图片本身很小其实 但是转gif就很大 转出来的gif的大小就大的唏嘘 寻找问题 这就是mp4的 ...

  10. Libvirtd networks -- 为libvirtd 中虚拟机指定ip遇到的问题

    backgroup 为libvirtd 中虚拟机指定ip,操作如下: virsh --connect qemu:///system dumpxml vm01 | grep "mac addr ...