java栈内存动态扩展要怎么理解?要如何实现?

TheDisguiser 2020-06-10 21:16:18 java常见问答 3556

小伙伴们知道如何在java栈中内存动态扩展吗?这是虚拟机中的一个概念,下面让我们一起来看看该如何实现吧。

一、内存概念

在java中,我们一般会简单把java内存区域划为两种:堆内存与栈内存。其实这种划分是比较粗粒度的。其中栈内存就是指的是虚拟机栈,堆内存指java堆

栈内存

实际为虚拟机栈。Java中每个方法被执行时都会同时创建一个栈帧,它会被用来存储局部变量、操作栈,动态链接,方法出口等信息。它的局部变量会包括各种基本类型的变量及对象的引用变量,且它们都是在方法的栈内存中分配。java局部变量所需内存空间一定是在编译期间完成的,当它进入一个方法时,这个方法所需的局部变量空间就已经确定,在方法运行期间一定不会改变。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间就能够立刻被另作他用。当线程请求的栈深度大于虚拟机所允许的深度,则抛出StackOverflowError异常。当虚拟机栈无法扩展时候则抛出OutOfMemoryError异常。

堆内存

堆内存唯一目的就是new出对象实例,它会在虚拟机启动时创建。它全部的对象实例与数组都需在堆上分配。堆是由垃圾回收负责的,所以也称为“GC堆”,垃圾回收采用的分代算法,堆因此分为新生代与老年代。堆的优势是可以动态地分配内存大小,生存期也不用事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但它有缺点,由于要在运行时动态分配内存,存取速度会较慢。

二、内存实现

动态扩展就是在栈空间不够的时候,自动加大栈的空间,避免StackOverflow异常,JVM是没有实现这个功能的。

动态栈一般有两种方法:Segmented stack和Stack copying:

Segmented stack

它可以这么理解,当一个双向链表把多个栈连接起来,它一开始只分配一个栈,当这个栈的空间不够时,就再分配一个,用链表一个一个连起来。

Stack copying

作用为在栈不够时,分配一个更大的栈,再把原来的栈复制过去。

使用函数alloca可以实现在栈上动态分配内存:

The
function alloca has the same calling sequence as malloc;
however, instead
    of allocating memory from the heap, the memory is allocated from the stack frame of the current
function.The advantage is that we don 't have to free the space; 
it goes away automatically when the
function returns.The alloca
function
increases the size of the stack frame.The disadvantage is that some systems
can 't support alloca, if it'
s impossible to increase the size of the stack frame
after the
function has been called.Nevertheless, many software packages use it
    , and implementations exist
for a wide variety of systems.

一般只支持Linux类型系统。

#include
void *alloca(size_t size);

以上就是关于java栈内存动态扩展的所以内容了,更多相关java入门知识,可以来我们的网站来了解详情噢。

推荐阅读:

java栈的制作代码是怎样的?java 栈实现

java栈和堆的区别是什么?java对于堆和栈的理解

java栈的特点是什么?java的堆和栈的优缺点介绍