学习Java语言需要学习一些和Java相关的底层原理,这将有利之后对于Java代码的理解和使用。本文将着重介绍Java中的JVM和堆栈内存的概念和区别。
JVM
JVM(全称Java Virtual Machine),也就是Java虚拟机。
Java程序在运行的时候都要开辟一个空间,也就是说任何软件在运行的时候都需要开辟空间,同样JVM也不例外,也需要开辟空间。JVM运行时在内存中开辟的内存区域,启动时在这片区域内自己还会进行更细致的划分,因为虚拟机中每片内存处理的方式都不一样,所以要分别单独进行管理。
JVM内存的划分主要是下列五个:
- 寄存器
- 本地方法去
- 方法区
- 栈内存
- 堆内存
栈内存
栈内存里面存储的都是局部变量。
什么是局部变量?凡是定义在方法中的都是局部变量,for循环内定义的也是局部变量。
先加载函数才能进行局部变量的定义,所以在方法进栈后,然后再定义变量,变量是有自己的作用域,一旦离开这个作用域,变量就会马上被释放。也因此,栈内存的更新速度非常快,这也是因为局部变量的生命周期都很短。
堆内存
new
建立的都是在堆中,堆中存放的都是实体(也就是对象)。int[] arr = new int[3];
在内存中是怎样被定义的?arr
的变量,但右边不是一个具体值,是一个实体。new
开辟了空间。内存在存储数据的时候,都是通过地址值来体现的,地址值是一块连续的二进制,然后给这个实体分配了一个内存地址。那么栈内存和堆内存要怎么联系起来?
前文提到,每个实体进入堆内存后,都被分配一个内存地址。把这个内存地址赋给变量arr
,arr
就可以通过地址找到数组。所以arr
想要操纵数组,就得通过地址,而不是直接把实体都赋给它。所以,这种我们不再称呼为基本数据类型,而是引用数据类型,称为arr
引用了堆内存当中的实体。
如果当 int[] arr = null;
arr
不做任何指向,null
的作用就是取消引用数据类型的指向。
当一个实体没有引用数据类型指向的时候,是不会被释放掉,而是会被当做垃圾。
Java有一个自动回收机制,会自动检测堆里是否存有垃圾,如果有,那么就会回收垃圾,但是至于什么时候回收就不一定了。
堆内存和栈内存的区别
通过以上内容,可以得出以下几点不同:
- 栈内存存储的是局部变量;堆内存存储的是实体。
- 栈内存的更新速度要快于堆内存,是因为局部变量的生命周期短。
- 栈内存存放的变量一旦结束就会释放;堆内存存放的实体会被垃圾回收机制不定时回收。