您的位置
主页 > 采购申报 » 正文

Java中堆内存和栈内存详解

来源:www.nazbcg.com 点击:947

作者:confuse Into

资料来源:

Java将内存分为两种类型,一种称为堆栈内存,另一种称为堆内存。

函数中定义的一些基本类型的变量和对象的引用变量在函数的堆栈存储器中分配。当在代码块中定义变量时,java会为堆栈上的变量分配内存空间。当超出变量的范围时,java会自动释放为变量分配的内存空间。内存空间可以立即用于其他目的。

堆内存用于存储由new创建的对象和数组。堆中分配的内存由java虚拟机自动垃圾收集器管理。在堆中生成数组或对象后,还可以在堆栈中定义特殊变量。此变量的值等于堆内存中数组或对象的第一个地址。堆栈中的这个特殊变量成为数组或对象的引用变量,您可以使用堆栈内存中的引用变量来访问堆中的数组或对象。引用变量等效于数组或对象的别名或代码。

引用变量是普通变量。定义它时,可以在堆栈上分配内存。引用变量在程序范围之外发布。数组和对象本身在堆中分配,即使程序运行到代码块,其中数组的语句和对象是使用new生成的,数组占用的堆内存和对象本身也不会被释放,并且在没有引用变量的情况下指向数组和对象。它只会变成垃圾而不能再使用,但它仍占用内存,并在不确定的时间被垃圾收集器释放。这也是java比较内存的主要原因。实际上,堆栈中的变量指向堆内存中的变量。这是Java中的指针!

java中的内存分配策略以及堆和堆栈的比较

1内存分配策略

根据编译原则,程序执行时有三种内存分配策略,即静态,堆栈和堆。

静态存储分配意味着可以在编译时确定运行时每个数据目标的存储空间要求,因此可以在编译时为它们分配固定的存储空间。此分配策略不需要程序代码中的变量。数据结构(例如可变数组)的存在不允许出现嵌套或递归结构,因为它们都会导致编译器无法计算确切的存储空间要求。

堆叠存储分配(也称为动态存储分配)由类似堆栈的运行堆栈实现。与静态存储分配相反,在堆叠存储方案中,程序对数据区域的要求在编译时是完全未知的。它只能在运行时才知道,但是当程序模块进入运行中的程序模块时,必须知道程序模块所需的数据区大小。它与我们在数据结构中知道的堆栈相同。堆栈存储分配根据高级和外向原则进行分配。

静态存储分配要求在编译时知道所有变量,堆栈存储分配要求在进程入口处知道所有存储要求,而堆存储分配专门负责数据结构的内存分配,其存储要求无法在编译时或在运行时模块的入口处,例如变量存储。长度字符串和对象实例。堆由大量可用或空闲块组成,堆中的内存可以按任何顺序分配和释放。

2个堆栈和堆栈之间的比较

上面的定义是从编译器的教科书中总结出来的。除静态存储分配外,它似乎很僵硬,难以理解。接下来,静态存储分配被放在一边,堆栈:被集中比较。

与堆栈和堆栈的功能和功能相比,堆栈主要用于存储对象,堆栈主要用于执行程序。这种差异主要是由于堆栈和堆栈的特性决定了:

在编程中,例如C/C ++,所有方法调用都是通过堆栈完成的,所有局部变量和形式参数都是从堆栈中分配的内存空间。实际上,它不是一个发行版。它只是堆叠顶部的传送带。 Stack Pointer会自动引导您到达放置物品的位置。你所要做的就是放下东西。退出函数时,可以通过修改堆栈指针来销毁堆栈的内容。应当注意,在分配例如要调用的程序模块的数据区域时,应事先知道数据区的大小。也就是说,虽然在程序运行时执行分配,但分配的大小或多或少是固定的和不变的。这个'size'是在编译时决定的,而不是在运行时。

堆是请求操作系统在运行时分配自己的内存的应用程序。由于操作系统管理的内存分配,分配和销毁需要时间,因此堆的效率非常低。但堆的优点是编译器不必知道从堆中分配多少存储空间,也不必知道存储数据保留在堆中需要多长时间,因此在使用堆保存数据时可以更灵活。堆。实际上,面向对象的多态性,堆内存分配是必不可少的,因为多态变量所需的存储空间只能在运行时创建对象之后才能确定。在C ++中,创建对象时,只需要使用new命令编译相关代码。执行此代码时,数据会自动保存在堆中。当然,为了实现这种灵活性,你将不可避免地付出代价。将需要更长的时间来分配堆中的存储空间!这正是我们刚才所说的效率低下的原因似乎是列宁很好。人的优点往往是人的缺点。人们的缺点往往是人们的优势(晕)。

JVM中的3堆和堆栈

JVM是基于堆栈的虚拟机。 JVM为每个新创建的线程分配一个堆栈。也就是说,对于Java程序,其操作是通过堆栈上的操作完成的。堆栈以帧为单位保存线程的状态。 JVM在堆栈上只执行两个操作。在帧中推送和弹出操作。

我们知道线程正在执行的方法称为该线程的当前方法。我们可能不知道当前方法使用的帧被称为当前帧。当线程激活Java方法时,JVM会将新帧推送到线程的Java堆栈中。该帧自然成为当前帧。在执行此方法期间,此框架将用于保存参数,局部变量,中间计算和其他数据。此框架与编译原理中的活动记录概念类似。/P>

从Java的分配机制来看,堆栈可以理解:堆栈是操作系统在建立进程或线程(操作系统中支持多线程的线程)时为线程建立的存储区域。该地区拥有先进的功能。

每个Java应用程序唯一对应一个JVM实例,每个实例唯一对应一个堆。应用程序动态创建的所有类实例或数组都放在此堆中,并由应用程序的所有线程共享。与C/C ++不同,Java中分配的堆内存会自动初始化。 Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用是在堆栈中分配的,也就是说,在创建对象时从两个地方分配内存,而堆中分配的内存实际上是创建此对象,并且堆栈中分配的内存只是堆对象的指针(引用)。

Java中的4个堆栈和堆栈

Java将内存分为两种类型:一种是堆栈内存,另一种是堆内存。

函数中定义的一些基本类型的变量和对象的引用变量在函数的堆栈存储器中分配。

当在代码块中定义变量时,Java会为堆栈上的变量分配内存空间。当超出变量的范围时,Java会自动释放为变量分配的内存空间。内存空间可以立即用于其他目的。

堆内存用于存储由new创建的对象和数组。

堆中分配的内存由Java虚拟机的自动垃圾收集器管理。

在堆中生成数组或对象之后,还可以在堆栈中定义一个特殊变量,以使堆栈中此变量的值等于堆内存中数组或对象的第一个地址。堆栈中的此变量成为数组或对象的引用变量。

引用变量等同于数组或对象的名称。您可以稍后使用堆栈中的引用变量来访问堆中的数组或对象。

具体做法是:

堆栈和堆都是Java在Ram中存储数据的地方。与C ++不同,Java自动管理堆栈和堆,程序员无法直接设置堆栈或堆。

Java的堆是一个运行时数据区,类(对象是从它们分配的空间。这些对象是由new,newarray,anewarray和multianewarray等指令创建的,它们不需要程序代码来显式释放。堆负责垃圾堆的优点是它可以动态分配内存大小,而生命周期不必事先告诉编译器,因为它在运行时动态分配内存,Java垃圾收集器会自动带走数据不再使用。缺点是由于在运行时动态分配内存,访问速度较慢。

堆栈的优点是访问速度比堆快,仅次于寄存器,堆栈数据可以共享。缺点是堆栈中数据的大小和生命周期必须是确定性的且不灵活。堆栈主要存储一些基本类型的变量(int,short,long,byte,float,double,boolean,char)和对象句柄。

堆栈具有非常重要的特性,即堆栈中的数据可以共享。假设我们还定义:

Int a=3;

Int b=3;

编译器首先处理int a=3;首先,它创建对堆栈中变量a的引用,然后查找堆栈中是否存在值3。如果未找到,则存储3,然后将a指向3.然后处理int b=3;在创建b的引用变量之后,b将直接指向3,因为堆栈中已有3个值。因此,存在a和b同时指向3的情况。这时,如果你让a=4;然后编译器将重新搜索堆栈中是否有4个值。如果没有,请存入4并指向4;如果它已经存在,请直接指向此地址。因此,a值的变化不会影响b的值。需要说明的是,这种数据共享不同于两个对象同时指向一个对象的引用,因为修改一个不影响b,它是由编译器完成的,有利于节省空间。对象引用变量修改对象的内部状态并影响另一个对象引用变量。