一、java虚拟机运行时数据区域主要分为:
1.程序计数器(PC寄存器)
2.java虚拟机栈:
全局变量(或者叫做字段,属性)在全局区(静态区)(我是把全局变量(成员变量)与实例变量等价,方法里的变量叫做局部变量。全局限量有默认值,局部变量没有默认值;或者全局变量、实例变量都叫实例变量,自己弄清楚就行)
(1)全局变量既不在堆中,也不在栈中,而是在全局区(静态区),全局变量的存储和静态变量是在一起的。(我的理解:全局变量与静态变量都是类的字段/属性,用Static修饰的叫做静态变量,但是类的不同对象共享一个静态变量,累的不同对象各自有自己的一个全局变量)。代码举例如下:(参见——————)
(2)初始化的全局变量和静态变量在同一块区域“数据段”;未初始化的全局变量和静态变量在相邻的另一块区域“数据段中的BSS段:特点是可读可写;在程序执行前BSS段会清0”
6.运行时常量池:
class文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量池。
Class 文件中的常量池(**编译器生成的字面量和符号引用**)会在类加载后被放入这个区域。
除了在编译期生成的常量,还允许动态生成,例如 String 类的 intern()。eg:"hello".intern(),但是常量是若已经存在了“hello”,就不插入。
【运行时常量池是方法区的一部分,注意jdk1.8中hotspot虚拟机实现方法区时候,是把方法区放在了元空间,运行时常量池挪到了堆中,见下图】
方法区的实现 | 运行时常量池所在位置 | 字符串常量池所在位置 | |
---|---|---|---|
JDK6 | PermGen space(永久代) | PermGen space(永久代) | PermGen space(永久代) |
JDK7 | PermGen space(永久代) | PermGen space(永久代) | Heap(堆) |
JDK8 | Metaspace(元空间) | Metaspace(元空间) |
①、将**Java虚拟机栈和本地方法栈合二为一;
②、元数据区取代了方法区,并且元数据区不在Java虚拟机中,而是在本地内存中。
③、运行时常量池由方法区中移到了堆中
方法区是一个 JVM 规范,永久代与元空间都是其一种实现方式。在 JDK 1.8 之后,原来永久代的数据被分到了堆和元空间中。静态变量和常量池等放入堆中,元空间存储类的元信息。
7.直接内存
在 JDK 1.4 中新引入了 NIO 类,它可以使 用 Native 函数库直接分配堆外内存,然后通过 Java 堆里的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在堆内存和堆外内存来回拷贝数据。