小伙伴们知道如何在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入门知识,可以来我们的网站来了解详情噢。
推荐阅读: