结合Java数据类型分析JVM运行时数据结构

阅读建议:本博客基于《Java编程思想》、《深入理解Java虚拟机》、《java并发编程实战》三本Java书籍和面试中遇到的问题而做的总结。

    JVM(JAVA Virtual Machine Java虚拟机)运行时数据区域:程序计数器、虚拟机栈(为执行Java方法服务)、本地方法栈(native方法服务)、堆(类实例)、方法区(类信息、常量、静态变量,即时编译器编译的代码),运行时常量池(用于存放编译期生成的各种字面值和符号引用典型的有String类的intern())。

线程私有的区域:程序计数器、虚拟机栈、本地方法栈。

线程共享区域:堆、方法区、运行时常量池。

一、方法区

1.static变量:

         在搞清楚静态变量前,首先必须先清楚类实例和类对象的区别:类实例和类对象是不同的概念。从面向对象的角度出发,所有一切都是对象,类本身是对象的一种,类对象是个抽象的概念;类的实例就是具体类的实例对象,类实例是具体的概念;其次必须清楚编译期(类的加载过程)与运行期JVM干了哪些事。

        静态变量与类实例无关,属于类对象的变量。静态变量在类加载的时候就已经初始化值了,并存放在静态存储区中,在运行期直接通过类对象调用就行;非静态变量需要new一个对象的实例,从对象实例中去获取,他是存放于堆中(对象)或者堆栈中(基本类型)。

        类的静态变量只占据一个存储空间,所有对象实例都共享该对象类的静态变量,也就是说所有new出来的对象实例,通过对象实例获取的静态字段的值都是取值同一个存储空间的值。不会因为new一个对象实例而增加一块存储空间来存储静态变量,因为静态变量在类加载的过程中就已经分配存储空间了,并且一次分配后就再也不会重新分配新的存储空间了。如果你通过不同的类实例去修改静态变量的值,其他其实获取静态变量的值就是已经改变后的值。

问题1:为什么调用static静态变量不需要创建任何对象,直接通过类.静态变量直接获取?

2.final常量

二、运行常量池

1.String类型:String是final修饰的类,对象实例存在于运行时常量池或堆中。

     a. 当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。

    b.String a = "hello world"与 String a = new String("hello world")是不同的对象,前者存储在运行时常量池,后者存放于堆中,二者存在不同的运行时数据区域中;存放在常量池中的好处是节约内存空间,String a = "hello world",如果运行时常量池里有这个字符串则句柄直接指向该字符串即可,若没有则创建该字符串并将句柄a指向该字符串。

      c.字符串为何设计成final类型呢?从继承、性能、并发安全上考虑。

4.基本数据类型:存放于堆栈中,便于高效存取。

5.数组

6.对象:

 

结合class文件结构以及类加载(加载、验证、准备、解析、初始化、使用、卸载)过程详细叙述以上变量的初始化过程,以及变量所在JVM运行时数据结构的位置。

说明:目前仅有提纲,后续会陆续补充

 

转载于:https://my.oschina.net/u/3556453/blog/1553321

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值