`
沉睡的鱼
  • 浏览: 69414 次
  • 性别: Icon_minigender_2
  • 来自: 石家庄
社区版块
存档分类
最新评论

从jvm管理角度看java类的静态属性和静态方法

阅读更多
JVM的内存分为两部分:stack和heap:

stack(栈)是JVM的内存指令区。stack管理很简单,push一定长度字节的数据或者指令,stack指针压栈相应的字节位移;pop一定字节长度数据或者指令,stack指针弹栈。stack的速度很快,管理很简单,并且每次操作的数据或者指令字节长度是已知的。所以Java基本数据类型,Java指令代码,常量都保存在stack中。

heap(堆)是JVM的内存数据区。heap的管理很复杂,每次分配不定长的内存空间,专门用来保存对象的实例。在heap中分配一定的内存来保存对象实例,实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型标记等,并不保存对象的方法(方法是指令,保存在stack中),在heap中分配一定的内存保存对象实例和对象的序列化比较类似。而对象实例在heap中分配好以后,需要在stack中保存一个4字节的heap内存地址,用来定位该对象实例在heap中的位置,便于找到该对象实例。

由于stack的内存管理是顺序分配的,而且定长,不存在内存回收问题;而heap则是随机分配内存,不定长度,存在内存分配和回收的问题;因此在JVM中另有一个GC进程,定期扫描heap,它根据stack中保存的4字节对象地址扫描heap,定位heap中这些对象,进行一些优化(例如合并空闲内存块什么的),并且假设heap中没有扫描到的区域都是空闲的,统统refresh(实际上是把stack中丢失了对象地址的无用对象清除了),这就是垃圾收集的过程。

我们首先要搞清楚的是什么是数据,什么是指令?然后要搞清楚对象的方法和对象的属性分别保存在哪里?

为了便于描述,我简单的统称:

1)方法本身是指令的操作码部分,保存在stack中;

2)方法内部变量作为指令的操作数部分,跟在指令的操作码之后,保存在stack中(实际上是简单类型保存在stack中,对象类型在stack中保存地址,在heap中保存值);

上述的指令操作码和指令操作数构成了完整的Java指令。

3)对象实例包括其属性值作为数据,保存在数据区heap中。

非静态的对象属性作为对象实例的一部分保存在heap中,而对象实例必须通过stack中保存的地址指针才能访问到。因此能否访问到对象实例以及它的非静态属性值完全取决于能否获得对象实例在stack中的地址指针。

先分析一下非静态方法和静态方法的区别:

非静态方法有一个和静态方法很重大的不同:非静态方法有一个隐含的传入参数,该参数是JVM给它的,和我们怎么写代码无关,这个隐含的参数就是对象实例在stack中的地址指针。因此非静态方法(在stack中的指令代码)总是可以找到自己的专用数据(在heap中的对象属性值)。当然非静态方法也必须获得该隐含参数,因此非静态方法在调用前,必须先new一个对象实例,获得stack中的地址指针,否则JVM将无法将隐含参数传给非静态方法。

而静态方法无此隐含参数,因此也不需要new对象,只要class文件被ClassLoader   load进入JVM的stack,该静态方法即可被调用。当然此时静态方法是存取不到heap中的对象属性的。

总结一下该过程:当一个class文件被ClassLoader   load进入JVM后,方法指令保存在stack中,此时heap区没有数据。然后程序技术器开始执行指令,如果是静态方法,直接依次执行指令代码,当然此时指令代码是不能访问heap数据区的;如果是非静态方法,由于隐含参数没有值,会报错。因此在非静态方法执行前,要先new对象,在heap中分配数据,并把stack中的地址指针交给非静态方法,这样程序技术器依次执行指令,而指令代码此时能够访问到heap数据区了。

再说一下静态属性和动态属性:

前面提到对象实例以及动态属性都是保存在heap中的,而heap必须通过stack中的地址指针才能够被指令(类的方法)访问到。因此可以推断出:静态属性是保存在stack中的(基本类型保存在stack中,对象类型地址保存在stack,值保存在heap中),而不同于动态属性保存在heap中。正因为都是在stack中,而stack中指令和数据都是定长的,因此很容易算出偏移量,也因此不管什么指令(类的方法),都可以访问到类的静态属性。也正因为静态属性被保存在stack中,所以具有了全局属性。

总结一下:静态属性保存在stack指令内存区,动态属性保存在heap数据内存区。
分享到:
评论

相关推荐

    java jvm内存模型

    局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。在JavaClass文件时,就在方法的Code属性的max locals数据项中确定了该方法所需要分配的最大局部变量表的容量。局部变量表的容量以变量...

    Java常见基础知识点.md

    * [面向对象和面向过程的区别](#面向对象和面向过程的区别) * [OracleJdk与OpenJdk的区别](#oraclejdk与openjdk的区别) ... * [静态属性方法和成员属性方法区别](#静态属性方法和成员属性方法区别) * [子类属性

    大学生java实习周记7篇.docx

    * 类继承:子类继承父类的所有属性和方法 * 构造方法:方法名称必须与类名相同,且没有返回值 * 重载:方法相同,参数类型不同,数量不同 * 重写:重写方法必须和被重写方法具有相同参数列表、相同方法和相同返回值 ...

    疯狂JAVA讲义

    学生提问:为什么静态内部类实例方法也不能访问外部类的实例属性呢? 207 学生提问:接口里是否能定义内部接口? 208 6.7.3 使用内部类 208 学生提问:既然内部类是外部类的成员,是否可以为外部类定义子类,在...

    深入理解Java虚拟机视频教程(jvm性能调优+内存模型+虚拟机原理)视频教程

    第101节方法调用-静态分派调用00:16:21分钟 | 第102节方法调用-动态分派调用00:09:02分钟 | 第103节动态类型语言支持00:09:27分钟 | 第104节字节码执行引擎小结00:03:38分钟 | 第105节总结与回顾00:10:55分钟

    java高级工程师面试题及答案.docx

    * 类和对象的关系:在 Java 中,类是对象的模板,定义了对象的属性和行为。对象是类的实例,拥有类的所有属性和行为。 * 继承和多态:Java 中的继承和多态是面向对象编程的两个基本概念。继承允许一个类继承另一个类...

    良心出品Java简答题.doc

    6. 类变量和实例变量、类方法和实例方法的区别:类变量是静态域,静态字段,或叫静态变量,它属于该类所有实例共有的属性。在内存中只有一个地方存储这个变量。实例变量是实例域,实例字段,或叫成员变量。类方法和...

    java 面试题 总结

     final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。 finally是异常处理语句结构的一部分,表示总是执行。 finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的...

    JAVA面试题最全集

    静态变量和静态方法的意义,如何引用一个类的静态变量或者静态方法? 50.JAVA语言如何进行异常处理,关键字:thorws,throw,try,catch,finally 51.Object类(或者其子类)的finalize()方法在什么情况下被调用? 52....

    java开发实习周记12篇.doc

    * 继承:子类继承父类的所有属性和方法 * 构造方法:方法名称必须与类名相同,且没有返回值 * 重载:方法相同,参数类型不同,数量不同 * 重写:重写方法必须和被重写方法具有相同参数列表、相同方法和相同返回值 * ...

    74个java面试题,只有题目没有答案

    Java API 文档是一种文档,用于描述 Java 类和方法的使用。 22. Java 日期和时间处理 * 如何在 Java 中进行日期和时间处理?使用 Date 和 Calendar 等类进行日期和时间处理。 23. Java 连接池 * 什么是连接池?...

    Java综合面试资料集

    3. 多态机制:Java 语言通过方法重写和方法重载来实现多态机制。 4. 类和接口:类是对象的模板,接口是类的抽象化。 5. 抽象类和接口的对比:抽象类可以继承其他类,接口不能继承其他类。 变量和方法知识点: 1. ...

    Java语言常用的方法名.pdf

    Java语言是面向对象的编程语言,其中有许多重要的概念和方法,本文将对其中的一些常用的方法名进行说明。 首先,abstract class,即抽象类,是不允许实例化的类,需要被扩展继承。abstract method,即抽象方法,不...

    java期末考试复习知识点摘要

    继承是面向对象编程的基本机制之一,它允许一个类继承另一个类的属性和方法。 二、图形编程 * paint() 方法使用 Graphics 类型的参数。 * 在编写 Java Applet 程序时,需在程序的开头写上 import java.applet....

    深入理解JVM内存结构及运行原理全套视频加资料.txt

    JVM是Java知识体系中的重要部分,对JVM底层的了解是每一位Java程序员深入Java技术领域的重要因素。本课程试图通过简单易懂的方式,系统的深入讲解JVM相关知识。包括JVM执行过程、虚拟机类加载机制、运行时数据区、GC...

    学会这些java面试题让你吊打面试官

    学会这些java面试题让你吊打面试官!面试前看看,让你充满自信,不再惧怕面试官各种刁难。1.Java中内存管理及各区域内存储...9.String中和Array中是否有length属性和length()方法? 10.==和equals的区别?。。。。。。

    Java核心编程技术源码

    Java高级特性:反射、泛型、注释符、自动装箱和拆箱、枚举类、可变参数、可变返回类型、增强循环、静态导入。随书附赠光盘内容为《Java高手真经(编程基础卷):Java核心编程技术》各种原型包、系统源程序。《Java高手...

    JAVA基础课程讲义

    JVM(JAVA VIRTUAL MACHINE) 16 Java运行时环境JRE(Java Runtime Environment) 17 JAVA语言应用范围 18 第一个JAVA程序 18 JAVA开发环境搭建 18 一个典型的JAVA程序的编写和运行过程 19 第一个程序常见错误 20 第一个...

    Java笔记总结.pdf

    包名所有字母一律小写,类名和接口名每个单词首字母大写,常量名所有字母都大写,单词之间用下划线分开,变量名和方法名的第一个单词小写,之后的每个单词首字母大写。 Java语言中有多种类型转换,包括强制类型转换...

    java基础名词解释汇总.docx

    javac是Java编译程序的名称,JVM是Java虚拟机,解释和执行Java字节码的程序,其中Java字节码由Java编译器生成。 在Java基础名词解释汇总中,关键字是Java中的保存字,不能用作其他的标识符。Layout managers是布局...

Global site tag (gtag.js) - Google Analytics