初步了解JavaJVM 及堆内存和栈内存的概念和区别

猿友 2021-07-15 17:17:43 浏览数 (3300)
反馈

学习Java语言需要学习一些和Java相关的底层原理,这将有利之后对于Java代码的理解和使用。本文将着重介绍Java中的JVM和堆栈内存的概念和区别。

JVM

JVM(全称Java Virtual Machine),也就是Java虚拟机。

Java程序在运行的时候都要开辟一个空间,也就是说任何软件在运行的时候都需要开辟空间,同样JVM也不例外,也需要开辟空间。JVM运行时在内存中开辟的内存区域,启动时在这片区域内自己还会进行更细致的划分,因为虚拟机中每片内存处理的方式都不一样,所以要分别单独进行管理。

JVM内存的划分主要是下列五个:

  1. 寄存器
  2. 本地方法去
  3. 方法区
  4. 栈内存
  5. 堆内存

栈内存

栈内存里面存储的都是局部变量。

什么是局部变量?凡是定义在方法中的都是局部变量,for循环内定义的也是局部变量。

先加载函数才能进行局部变量的定义,所以在方法进栈后,然后再定义变量,变量是有自己的作用域,一旦离开这个作用域,变量就会马上被释放。也因此,栈内存的更新速度非常快,这也是因为局部变量的生命周期都很短。


堆内存

堆内存里面存储的是数组和对象。(数组也算是对象的一种。)
什么是对象?凡是​new​建立的都是在堆中,堆中存放的都是实体(也就是对象)。
实体用于封装数据,而是封装了多个,如果一个数据消失,这个实体却没消失,则还可以使用。所以堆是不会随时释放的,但是栈就不一样了,栈里面存放的都是单个变量,变量被释放了,就消失了。堆里的实体虽然不会被释放,但会被Java垃圾回收机制当做垃圾不定时的收取。

例子:
int[] arr = new int[3];​在内存中是怎样被定义的?
栈内存和堆内存图例1
如图所示,主函数首先进入了栈中,在栈中定义了一个​arr​的变量,但右边不是一个具体值,是一个实体。
实体是被创建在堆内存里面的,在堆里面首先通过​new​开辟了空间。内存在存储数据的时候,都是通过地址值来体现的,地址值是一块连续的二进制,然后给这个实体分配了一个内存地址。
数组都是有一个索引,数组这个实体在堆内存中产生后每一个空间都会进行默认的初始化,不同的类型初始化的值不一样。
所以在栈和堆当中分别创建了变量和实体。
    栈内存和堆内存的图例2

那么栈内存和堆内存要怎么联系起来?

前文提到,每个实体进入堆内存后,都被分配一个内存地址。把这个内存地址赋给变量​arr​,​arr​就可以通过地址找到数组。所以​arr​想要操纵数组,就得通过地址,而不是直接把实体都赋给它。所以,这种我们不再称呼为基本数据类型,而是引用数据类型,称为​arr​引用了堆内存当中的实体。


如果当 ​int[] arr = null;

arr​不做任何指向,​null​的作用就是取消引用数据类型的指向。

当一个实体没有引用数据类型指向的时候,是不会被释放掉,而是会被当做垃圾。

Java有一个自动回收机制,会自动检测堆里是否存有垃圾,如果有,那么就会回收垃圾,但是至于什么时候回收就不一定了。


堆内存和栈内存的区别

通过以上内容,可以得出以下几点不同:

  • 栈内存存储的是局部变量;堆内存存储的是实体。
  • 栈内存的更新速度要快于堆内存,是因为局部变量的生命周期短。
  • 栈内存存放的变量一旦结束就会释放;堆内存存放的实体会被垃圾回收机制不定时回收。

总结

以上就是关于Java底层JVM,以及JVM下的栈内存和堆内存简要知识点的全部内容。如果还想要了解更多关于Java底层知识的小伙伴,请多多关注并支持W3Cschool


0 人点赞