概述
对从事C和C++的程序员来说,在内存管理方面,他们既是拥有最高权利的人,也是从事最基础工作的“劳动人民”。
而对于Java程序员来说,JVM自动进行内存管理,程序员不再需要为每一个new操作去写配对的delete/free代码,不容易出现内存泄露和内存溢出问题。
但是,正因为JVM帮我们管理了内存,一旦出现内存泄露或溢出问题,如果不了解虚拟机是怎么管理内存的,那么排查错误会成为一项异常艰难的工作
So, 小伙伴们,走起,让我带你们进入JVM的内存世界!
运行时数据区域(Run-Time Data Areas)
首先,叫“Java内存分配”并不是我本意,我是为了能让大家搜索进来才起的这个名字,Java(JVM)关于内存的管理是一个叫:“运行时数据区”的章节
JVM在运行时(运行时就是执行Java程序时)根据《Java虚拟机规范(Java SE 7)》的规定,会包括如下几个运行时数据区域
1. 程序计数器(Program Counter Register)
或者叫:程序计数寄存器、PC寄存器,学过计算机组成原理应该就懂
a. 作用
程序计数器是一块较小的内存空间,可以看做是当前线程(Thread)所执行的字节码的行号指示器
在JVM概念模型中(各种JVM可能并不依照此开发),解释器(Interpreter)就是通过改变这个计数器的值来选取下一条需要执行的字节码指令
为了在线程切换后能恢复到正确的执行位置,每条线程都有一个独立的程序计数器。这种内存区域称为“线程私有”的内存
- 线程正在执行Java方法时,计数器记录的是虚拟机字节码指令的地址;如果执行的是Native方法,则计数器值为空(Undefined)
b. Error
这块内存是JVM规范中唯一没有规定任何OutOfMemoryError的区域
2. 虚拟机栈(Virtual Machine Stacks)
也是线程私有的,其生命周期和线程一样,每个Java线程有一个虚拟机栈
a. 作用
虚拟机栈描述的是Java方法执行的内存模型,即:每个方法在执行的时候都会创