文章目录
0、前言
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的"高墙",墙外面的人想进去,墙里面的人却想出来。
——《深入理解Java虚拟机-JVM高级特性与最佳实践》
Java作为一种高级编程语言,得以大行其道的一个重要因素就是所依赖的运行环境Java虚拟机(JVM)的良好发展。JVM使得Java程序具有了平台无关性的优势,在PC端和各种移动终端都有良好的运行表现。
所谓平台无关性,是指JVM保证了Java程序能在多平台间进行无缝移植,即编译一次,处处运行。其原理是:JVM屏蔽了具体平台相关的信息,使Java语言编译程序只需要生成目标字节码(.class),由 JVM 把字节码解释成具体平台上的机器指令,就可以在多种平台上不加修改地运行,而非直接在硬件系统的 CPU 上执行。
说白了就是,JVM把Java程序解释成JVM能懂的语言(字节码),JVM在运行时负责把这一套语言解释成物理计算机器能懂的语言(具体的机器指令)。
JVM作为Java程序运行的载体,其重要特征就是自动的内存管理,内存管理主要包括内存分配(内存模型)和垃圾收集技术两部分。
1、什么是JVM内存模型
JVM的内存模型又叫JVM运行时数据区域。
Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干不同的运行时数据区域。这些区域用途各异,生命周期也各不相同。
2、JVM的内存模型构成
JVM的内存模型主要包括:堆内存、方法区(包括运行时常量池)、栈内存(包括虚拟机栈和本地方法栈)、程序计数器。
从共享范围上来划分可分为两类:线程共享区域(堆和方法区);线程私有区域(虚拟机栈、本地方法栈和程序计数器)。
从堆概念来划分可分为两类:堆内存和非堆内存。
JVM运行时数据区:
JVM内存的拓扑结构图:
PS:
在JDK8之前,永久代(permanent generation)是HotSpot JVM特有的概念,是方法区(JVM规范)的异一种实现。永久代是一片连续的堆空间。JDK8以后,JVM不再有永久代(PermGen)。但类的元数据信息(metadata)还在,只不过不再是存储在连续的堆空间上,而是移动到叫做“Metaspace”的本地内存(Native memory)
1.1、堆
1.1.1、什么是堆
这里所说的堆要区别与数据结构中的堆(完全二叉树),这里所说的堆是JVM所管理的最大的一块内存区域,是被所有线程共享。
1.1.2、堆的作用
Java作为一门面向对象的编程语言,其程序运行的过程,是对象实例从创建到消亡的过程。堆就是用来存储Java对象和数组的内存区域。
1.1.3、堆的特点
- 堆内存被所有线程共享;
- 堆在JVM启动时就被创建了;
- 垃圾回收就是回收此区域的内存;
- new 出来的对象都存在堆中;
- 因为堆的线程共享特点,在给对象和数组分配内存时需要加锁。
1.1.4、堆内存的分区
堆内存从组成上来说主要划分为新生代和老年代,其中新生代又分为Eden区、Fro