《透过OOP-Klass模型来看实例变量与类变量的存储》
前言
很久没有写过博客了,但今天在Iteye上看见有朋友提问静态变量是存储在方法区还是存储在哪里的一篇帖子,然后又搜索了其他的一些相关帖子,看后心里不免有些蛋疼,十有八九很多人从心里根本不清楚JVM是如何存储的,或者说,很多人根本就没有区分开什么是变量存储什么是值存储,这2个压根就不是同一个概念,导致很多人产生疑问,那么笔者今天这篇博客,要的效果就是深入到JVM底层来分析这个问题。当然由于本人能力有限,难免会有语义错误的地方,请大家指出。
正文
言归正传,再谈存储之前,首先做一个扫盲。从虚拟机内部表示形式来看,变量可以划分为实例变量和类变量(即静态变量)。实例变量与对象实例相关,也就是说,任何一个实例变量,在使用之前,首先要做的事情就是目标类型必须要实例化,然后才能够使用;而类变量与对象实例无关,但是却以类相关,也就是说,使用一个被static关键字标示的类变量是不用实例化对象的,直接可用。
当大家明白实例变量和类变量之前的区别后,我们再接从语法层面开始讨论引用类型的变量和原始类型的变量之间的区别。引用类型的变量所持有的值是什么?相信大家都应该知道,所谓引用指的就是一个指向目标对象实例的类似于“指针”的东西,而原始类型的变量所持有的值就是实际的原始值。
关于变量的概念已经介绍了一大堆后,接下来我们来再来看看变量值的存储。以粗粒度的方式来看待变量的存储尽管有些不妥,但为了让更多不理解JVM底层的人能够看懂,也是情有可原。Java的运行时数据区中,栈帧中的局部变量表用于存储方法体内的局部变量和方法参数,如果变量的类型是原始数据类型,则在局部变量表中存储实际的原始值,反之存储对象引用(reference),当然还会存储returnAddress类型。那么如果是成员变量,就存储在Java堆区中(内存布局中的实例数据中)。简单来说,与线程上下文相关的存储在Java栈中,反之存储在Java堆中,这个是常识。
图1 对象访问定位
之所以先说变量值的存储而没有先说变量的存储,笔者是可以安排的,因为这2个概念是非常多的开发人员容易弄混淆的。变量仅仅只是一个存储介质,所负责的任务很简单,就是牵引数据存储到正确的位置上,但它自己本身没有任何能力存储数据,这一点要明确。这里要引入一个概念,那就是JVM中对象的底层表示形式,OOP-Klass模型。对象内存布局中的内存头是由instanceOopDesc来表示(数组类型则用arrayOopDesc对象来进行表示),而对象头中的元数据指针所指向的当前对象的目标类型则是由Klass中的instanceKlass对象进行表示(数组则用arrayKlass对象进行表示)。OOP与Klass其实是2个相互独立但是却又彼此相互关联的模块,这2个模块均包含在/openjdk/hotspot/src/share/vm/oops模块中,那么OOP-Klass模型与对象的内存布局之间又有什么关系呢?在JVM中对象头就是由OOP对象instanceOopDesc来表示(数组类型则用arrayOopDesc对象来进行表示),而对象头中的元数据指针所指向的当前对象的目标类型则是由Klass中的instanceKlass对象进行表示(数组则用arrayKlass对象进行表示),用于在JVM中表示一个Java类的对等体。当明确OOP-Klass模型的作用后,请大家思考一下JVM是如何通过栈帧中的对象引用访问到其内部的对象实例的呢?如图1所示,JVM可以通过对象引用准确定位到Java堆区中的instanceOopDesc对象,这样既可成功访问到对象的实例信息,当需要访问目标对象的具体类型时,JVM则会通过存储在instanceOopDesc中的元数据指针定位到存储在方法区中的instanceKlass对象上。
扯了一大堆,说白了,类变量既然不予对象实例相关,那么它则存储在方法区中的instanceKlass对象内,当然仅仅只是变量!
相关推荐
标题中的"16M-OOP-源码"表明...总结,"16M-OOP-源码"可能包含了大量的面向对象编程实例,涵盖各种类定义、继承关系、多态实现以及可能的设计模式。通过深入研究这个代码库,开发者可以增强对OOP的理解,提升编程能力。
标题中的"project-oop-1-源码"表明这是一个关于面向对象编程(Object-Oriented Programming,简称OOP)的项目,可能是一个教学实例或者一个实际应用的代码库。源码通常包含了项目的全部代码文件,我们可以从中学习到...
Java面向对象编程(OOP)是Java编程的核心概念,它将现实世界中的实体抽象为类,然后通过实例化这些类来创建对象,以此来模拟现实世界的模型。以下是关于Java OOP的一些关键知识点: 3.1 类: 类是Java OOP的基本...
面向对象编程(Object-Oriented Programming,简称OOP)是C++语言的核心特性之一,它是一种编程范式,强调通过对象来组织代码,使得程序更易于理解和维护。本资料"oop--cplusplus.rar"包含了深入学习C++面向对象编程...
- **成员变量**:抽象类可以有实例变量,而接口只能有常量(final static)。 - **方法**:抽象类可以有抽象方法和非抽象方法,接口只能有抽象方法(在Java 8之后可以有默认方法和静态方法)。 - **继承关系**:...
根据提供的文件信息:“JavaOOP-myPrime.txt”,我们可以推断出这份文档主要关注的是Java面向对象编程(Object-Oriented Programming, OOP)中的某个特定主题或案例——可能是与质数(prime numbers)相关的实现。...
根据提供的文件信息,“JavaOOP-pet.txt”,我们可以推测这份文档可能涉及面向对象编程(Object-Oriented Programming,简称OOP)在Java中的应用,并且可能包含了一个宠物类(Pet class)或者与宠物相关的示例代码。...
ABAP-OOP-Library, 面向对象的编程库 ABAP对象定位程序库安装手动创建下面列出的字典类型使用基于源类编辑器和常规编辑器来导入所有类。接口和程序。某些软件包使用邮件类。 这些消息保存在。messageclass 。txt文件...
1. **类与对象**:Java是一种面向对象的语言,它通过类来定义数据结构和操作数据的方法。类是对象的蓝图,而对象则是类的实例。 2. **封装**:Java通过访问修饰符(如private, public, protected)实现封装,将数据...
php-oop-fundamentals, 这个库伴随着Tuts+课程 PHP OOP基础 php-oop-fundamentals这个库伴随着Tuts+课程 PHP OOP基础什么是 OOP?在本课中,我们将看看面向对象的编程是什么,完全正确。 这看起来可以能很多,但是你...
面向对象编程(Object-Oriented Programming,简称OOP)是C++语言中的核心特性,它是一种编程范式,强调程序数据结构与程序控制结构的结合,以提高代码的可重用性和可维护性。在本文件集合中,我们可以通过三个文件...
它们决定了类、方法和变量的可见性和可访问范围。 8. **异常处理**:Java通过异常处理机制来处理程序运行时可能出现的错误。我们可以使用try-catch-finally语句块来捕获和处理异常。 9. **集合框架**:Java集合...
静态方法与类相关联,而不是与类的任何特定实例相关联。这意味着静态方法不能直接访问非静态的成员(变量或方法),因为非静态成员是与每个对象实例相关的。静态方法通常用于不需要访问对象状态的工具函数或者操作,...
在“作业答案oop-day02”这个文件中,可能包含了以上知识点的具体应用示例,包括但不限于如何定义和实例化类、如何实现封装、如何使用继承和多态等。通过分析这些解答,学习者可以检查自己的理解是否正确,或者借鉴...
堆是存储对象实例的地方,而栈则保存方法调用时的局部变量。在上述代码中,`math` 变量在栈中创建,而 `Math` 对象实例在堆中创建。当构造方法执行完毕,局部变量 `math` 会保留对堆中对象的引用,但构造方法的参数...
首先,从标题和描述来看,这是一份关于Java面向对象编程的笔记,重点介绍了类和对象的概念。面向对象编程与面向过程编程的主要区别在于,面向过程编程关注的是执行步骤,而面向对象编程则关注对象的交互。在Java中,...
类的实例化过程就是创建对象。属性用来存储数据,而方法则是操作数据的函数。类的封装性保证了对象内部状态的隐私,只对外提供必要的接口进行交互。 继承是OOP的另一个关键特性,它允许一个类(子类)继承另一个类...
本课程由IT十八掌徐培成讲解的"Java基础第04天-04.OOP-堆栈的溢出与设置-private关键字"深入探讨了两个关键主题:堆栈溢出和private关键字的使用。 首先,让我们来理解堆栈溢出。在计算机编程中,内存分为堆和栈两...
4. **类和成员变量**:类中的变量被称为成员变量,它们在其他类中不能直接使用,需要通过对象来访问。局部变量只在其定义的方法或代码块中有效。调用类的方法需要使用对象名.方法名,如果是类方法(静态方法),则...
"exo-oop-oop-1"这个标题可能是指一个关于JavaScript面向对象编程(Object-Oriented Programming, OOP)的学习项目或者教程,其中"oop"是OOP的缩写,暗示我们将深入探讨JavaScript中的类、对象、封装、继承和多态等...