C++的模板类在HotSpot VM中的应用
模板是c++的一种特性,允许函数或者类通过泛型(generic types)的形式表现或者运行。模板可以使得函数或类在对应不同的类型(types)的时候正常工作,而无需为每一种类型分别写一份代码。
在HotSpot VM中定义了一些模板类,有了这些模板类,我们就可以和Java一样进行泛型编程。HotSpot VM中定义了Dictionary和SymbolTable等用来存储类和字符串等内容的Hash表,这些容器类都使用到了模板类。
看一下具体的定义,如下:
源代码位置:/media/mazhi/sourcecode/workspace/projectjava9/learnhotspot/src/utilities/hashtable.hpp
template <MEMFLAGS F> class BasicHashtable : public CHeapObj<F> {
...
private:
int _table_size;
HashtableBucket<F>* _buckets;
BasicHashtableEntry<F>* bucket(int i);
...
}
template <MEMFLAGS F> class BasicHashtableEntry : public CHeapObj<F> {
private:
unsigned int _hash;
BasicHashtableEntry<F>* _next;
...
}
定义了一个名称为BasicHashtable的类模板,类模板以template关键字开始,后面跟着模板参数列表。这里在模板中定义了一个非类型参数,一个非类型参数表示一个值而不是一个类型。它的定义如下:
typedef unsigned short MEMFLAGS;
其定义的非类型参数F也应用到了类模板HashtableBucket<F>中了,同样也可以应用到函数的参数和返回类型中。
通过BasicHashtable这个类模板的定义可以看出,通过此类模板生成的表或字典是通过列表来解决Hash冲突的。
下面接着看另外一个类模板,如下:
源代码位置:/media/mazhi/sourcecode/workspace/projectjava9/learnhotspot/src/utilities/hashtable.hpp
template <class T, MEMFLAGS F> class Hashtable : public BasicHashtable<F> {
protected:
...
HashtableEntry<T, F>* bucket(int i) {
return (HashtableEntry<T, F>*)BasicHashtable<F>::bucket(i);
}
}
template <class T, MEMFLAGS F> class HashtableEntry : public BasicHashtableEntry<F> {
private:
T _literal; // ref to item in table.
...
}
这次的类模板继承了BasicHashtable<F>,不过这个类模板中通过class关键字定义了一个模板类型参数T,这其实就是我们要真正往Hash表中存储的元素的类型。
SymbolTable和StringTable都使用了如上的类模板,如SymbolTable类的定义如下:
class SymbolTable : public Hashtable<Symbol*, mtSymbol> {
...
}
为类型模板参数指定了具体的类型。也就是这个Hash表中存储的元素类型为Symbol*,而在为这些元素分配内存时,将这些内存统计到mtSymbol上,这样NMT就能追踪这一部分使用内存的详细信息了。
下面看一下存储类的字典的定义,如下:
template <class T, MEMFLAGS F> class TwoOopHashtable : public Hashtable<T, F> {
...
}
class Dictionary : public TwoOopHashtable<Klass*, mtClass> {
...
}
存储Java类的字典Dictionary继承了TwoOopHashtable<Klass*,mtClass>,这是因为在Java世界中,只有类全名和类加载器才能唯一表示一个类,所以继承这个类也起到了一个见名知义的效果。
另外还有一点需要说明,就是C++对模板的分离式编译很弱。对于 BasicHashtable 中定义的bucket()函数来说,其实现是在hashtable.cpp文件中,其实严格来说,这不是函数的定义,而是生成定义的一种方案,只有在实例化时,才能生成函数定义,所以我们能在hashtable.cpp文件中看到如下类似的语句:
template class BasicHashtable<mtSymbol>;
在.cpp文件的末尾加上如上代码来显式实例化,这样我们将hashtable.cpp作为源文件加入编译时,整个程序就有了模板的显式实例化,即函数定义。否则可能报"undefined reference to"相关的错误。
本人最近准备出一个手写Hotspot VM的课程,超级硬核,从0开始写HotSpot VM,将HotSpot VM所有核心的实现全部走一遍,如感兴趣,加我速速入群。
群里可讨论虚拟机和Java性能剖析与故障诊断等话题,欢迎加入。

C++的模板类在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 ...
- 如何在模板类中使用这些point类型?
博客转载自:http://www.pclcn.org/study/shownews.php?lang=cn&id=271 由于PCL模块较多,并且是一个模板库,在一个源文件里包含很多PCL算法 ...
- 解析Spring第四天(Spring中的事物、Spring框架来管理模板类)
JDBC模板技术: Spring框架中提供了很多持久层的模板类来简化编程,使用模板类编写程序会变的简单 template 模板 都是Spring框架提供XxxTemplate 提供了JDBC模板,Sp ...
- HotSpot VM运行时
HotSpot VM运行时系统为HotSpot JIT编译器和垃圾收集器提供服务和通用API,同时还为VM提供启动.线程管理.JNI(Java本地接口)等基本功能.HotSpot VM运行时环境担当许 ...
- 转:什么是即时编译(JIT)!?OpenJDK HotSpot VM剖析
重点 应用程序可以选择一个适当的即时编译器来进行接近机器级的性能优化. 分层编译由五层编译构成. 分层编译提供了极好的启动性能,并指导编译的下一层编译器提供高性能优化. 提供即时编译相关诊断信息的JV ...
- 如何用boost::serialization去序列化派生模板类(续)
在 如何用boost::serialization去序列化派生模板类这篇文章中,介绍了序列化派生类模板类, 在写測试用例时一直出现编译错误,调了非常久也没跳出来,今天偶然试了一下...竟然调了出来. ...
- 实现C++模板类头文件和实现文件分离的方法
如何实现C++模板类头文件和实现文件分离,这个问题和编译器有关. 引用<<C++primer(第四版)>>里的观点:1)标准C++为编译模板代码定义了两种模型:“包含”模型和“ ...
- C++模板类头文件和实现文件分离
http://www.cnblogs.com/lvdongjie/p/4288373.html 如何实现C++模板类头文件和实现文件分离,这个问题和编译器有关. 引用<<C++primer ...
- 如何在动态链接库dll/so中导出自定义的模板类template class | how to implement a template class with c++ and export in dll/so
本文首发于个人博客https://kezunlin.me/post/4ec4ae49/,欢迎阅读最新内容! how to implement a template class with c++ and ...
随机推荐
- 聊聊Flink CDC必知必会
CDC是(Change Data Capture变更数据获取)的简称. 核心思想是,监测并捕获数据库的变动(包括数据 或 数据表的插入INSERT.更新UPDATE.删除DELETE等),将这些变更按 ...
- 【技术积累】Mysql中的SQL语言【一】
建表语句 后续所有内容建立在这些SQL语句上 CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(50), age INT ); CREATE ...
- Cisco show interface 命令详解
Router#show interface f0/2 FastEthernet0/2 is up, line protocol is up Hardware is Lance, address is ...
- Windows查询进程和杀死进程
查询进程 查询进程占用的端口(通过端口查询) netstat -ano |findstr "端口号" 杀死进程 通过进程号查看所属进程名称 tasklist |findstr &q ...
- Easygraph:全面高效的图分析与社会计算开源工具
前言图是对事物之间关系的一种原生的表达,利用图可以深入直接地认识世界中的关联.社交网络.交易数据.知识图谱.交通运输.生物技术等都是图数据的典型应用.社交网络是一种特殊的图数据,它建立在图网络的基础上 ...
- 引入代码来源:深入分析markdown-it-quote插件的魔法
引入代码来源:深入分析markdown-it-quote插件的魔法 markdown-it-quote是一个用于markdown-it的插件,支持多种代码围栏功能. 这是 SourceCodeTrac ...
- 【算法】单调栈 & 单调队列学习笔记
1. 单调栈简介 1.1 前言 今天是 2023/1/15,一中寒假集训阶段性的结束了.集训的学习笔记可以在本人 blogs 的[算法]标签栏中找. 马上就要过年了,提前祝大家新年快乐! 1.2 什么 ...
- 关于 Task 简单梳理(C#)【并发编程系列】
〇.前言 Task 是微软在 .Net 4.0 时代推出来的,也是微软极力推荐的一种多线程的处理方式. 在 Task 之前有一个高效多线程操作类 ThreadPool,虽然线程池相对于 Thread, ...
- [nginx]反向代理grpc
前言 nginx从1.13.10版本开始提供对gRPC代理的支持.由于grpc基于http2,因此编译nginx时需要添加参数--with-http_v2_module来启用对http2协议的支持. ...
- [clickhouse]同步MySQL
前言 clickhouse的查询速度非常快,而且兼容大部分MySQL的sql语法,因此一般将clickhouse作为MySQL的读库. 本文提供两种clickhouse同步MySQL的方式 click ...