JAVA的OOP-Klass内存模型

498 阅读3分钟

JAVA的OOP-Klass内存模型

什么是OOP-Klass模型

HotSpot是基于c++实现,而c++是一门面向对象的语言,本身具备面向对象基本特征,所以Java中的对象表示,最简单的做法是为每个Java类生成一个c++类与之对应。但HotSpot JVM并没有这么做,而是设计一个OOP-Klass Model

这里的 OOP 指的是 Ordinary Object Pointer (普通对象指针),它用来表示对象的实例信息,是藏在指针里的对象。而 Klass 则包含元数据和方法信息,用来描述Java类。

为什么才有OOP-Klass模型

之所以采用这个模型是因为HotSopt JVM的设计者不想让每个对象中都含有一个vtable(虚函数表) ,所以就把对象模型拆成klass和oop,其中oop中不含有任何虚函数,而Klass就含有虚函数表,可以进行method dispatch(方法派遣)。

OOP与Klass用处

Klass介绍

Klass主要有两个功能:

  • 实现语言层面的Java类
  • 实现Java对象的分发功能

注意:一般jvm在加载class文件时,会在方法区创建instanceKlass,表示其元数据,包括常量池、字段、方法等。

OOP介绍

OOP对象包含以下几个部分:

  • instanceOopDesc,也叫对象头,由一下两部分组成:

    • Mark Word:主要存储对象运行时记录信息,如hashcode,GC分代年龄,锁状态标志,线程ID,时间戳等
    • 元数据指针:即指向方法区的instanceKlass实例。
  • 实例数据

注意:Klass是在class文件在加载过程中创建的,OOP则是在Java程序运行过程中new对象时创建的。

C++中的虚函数

概述

在C++中每一个有虚函数的类,都有vtable(虚函数表)。

什么是虚函数:

同Java方法(函数),C++中有虚函数的概念,用virtual关键字来表示,每个类都会有一个虚函数表,该虚函数表首先会从父类中继承得到父类的虚函数表, 如果子类中重写了父类的虚函数,要调用哪个虚函数,是根据当前实际的对象来判断的,指针当前指向的是哪种类型的对象,就调用哪个类型中类定义的虚函数。每个类只有一张虚拟函数表,所有的对象共用这张表。在Java中,自动实现了虚函数这一概念,就是我们说的多态。

什么是纯虚函数:

同Java抽象方法,C++中主要特征是不能被用来声明对象,是抽象类,是用来确保程序结构与应用域的结构据具有直接映射关系的设计工具。带有纯虚函数的类称为抽象类,抽象类能被子类 继承使用,在子类中必须给出纯虚函数的实现,如果子类未给出该纯虚函数的实现,那么该子类也是抽象类,只有在子类不存在纯虚函数时,子类才可以用来声明对象!抽象类也能用于声明指针或引用,或用于函数声明中。具有抽象类特性的类还有构造函数和析构函数,全部是保护的类。如果没有给出纯虚函数的实现,则在它 所在的类的构造函数或析构函数中不能直接或间接的调用它。纯虚函数的实现可以在类声明外进行定义。

C++的抽象类:

同Java抽象类,C++中指同时含有纯虚函数和非纯虚函数的类

C++的纯虚类:

同Java接口,C++中指只含有纯虚函数的类

与Java的区别

3.jpg

拓展: C++中普通函数不存在多态,它不会根据实际的对象来判断调用函数,而是直接调用当前变量类型的方法。

实例说明

1.jpg

2.jpg