阅读建议:本博客基于《Java编程思想》、《深刻理解Java虚拟机》、《java并发编程实战》三本Java书籍和面试中遇到的问题而作的总结。java
JVM(JAVA Virtual Machine Java虚拟机)运行时数据区域:程序计数器、虚拟机栈(为执行Java方法服务)、本地方法栈(native方法服务)、堆(类实例)、方法区(类信息、常量、静态变量,即时编译器编译的代码),运行时常量池(用于存放编译期生成的各类字面值和符号引用典型的有String类的intern())。面试
线程私有的区域:程序计数器、虚拟机栈、本地方法栈。编程
线程共享区域:堆、方法区、运行时常量池。数组
1、方法区安全
1.static变量:数据结构
在搞清楚静态变量前,首先必须先清楚类实例和类对象的区别:类实例和类对象是不一样的概念。从面向对象的角度出发,全部一切都是对象,类自己是对象的一种,类对象是个抽象的概念;类的实例就是具体类的实例对象,类实例是具体的概念;其次必须清楚编译期(类的加载过程)与运行期JVM干了哪些事。并发
静态变量与类实例无关,属于类对象的变量。静态变量在类加载的时候就已经初始化值了,并存放在静态存储区中,在运行期直接经过类对象调用就行;非静态变量须要new一个对象的实例,从对象实例中去获取,他是存放于堆中(对象)或者堆栈中(基本类型)。性能
类的静态变量只占据一个存储空间,全部对象实例都共享该对象类的静态变量,也就是说全部new出来的对象实例,经过对象实例获取的静态字段的值都是取值同一个存储空间的值。不会由于new一个对象实例而增长一块存储空间来存储静态变量,由于静态变量在类加载的过程当中就已经分配存储空间了,而且一次分配后就不再会从新分配新的存储空间了。若是你经过不一样的类实例去修改静态变量的值,其余其实获取静态变量的值就是已经改变后的值。spa
问题1:为何调用static静态变量不须要建立任何对象,直接经过类.静态变量直接获取?线程
2.final常量
2、运行常量池
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运行时数据结构的位置。
说明:目前仅有提纲,后续会陆续补充