我的编程空间,编程开发者的网络收藏夹
学习永远不晚

浅谈一下Java中的堆和栈

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

浅谈一下Java中的堆和栈

Java数据类型在执行过程中存储在两种不同形式的内存中:栈和堆,它们通常由运行Java虚拟机(JVM)的底层平台维护。本文从Java软件开发的角度提供了对这两种内存类型的一些见解。

Java程序是怎么运行的

Java程序运行在Java Virtual Machine (JVM)中,JVM提供了Java应用程序在运行时所需要的任何资源的管理器。这就意味着开发者写的应用程序或者创建的应用程序没有能力去直接获取系统资源(不管是硬件还是软件),除非JVM能提供给这些资源。所以在Java中,程序运行顺序如下图:

JVM层使得Java平台能够独立运行,其他编程语言,例如C/C++没有使用类似JVM层的东西,因此它们不是跨平台的语言,即使它们是可移植的语言。它们就像下图一样:

这两种形式有优点也有缺点,Java已经有了自己的生态系统。与此同时,像C/C++这样的编程语言能够直接访问系统资源,从而更有利于优化核心单元的使用,从而产生超级快速和高效的程序。但两者在软件开发领域都有各自的用途。

所有编程语言在编译和执行过程中都有许多相似之处。其中最重要的一点就是内存管理,无论使用哪种语言,内存管理对程序的整体效率都有重要影响,因为管理好内存资源,从而才能管理好应用程序性能。

Java中的运行内存

应用程序之间的一个常见现象是,每个应用程序都需要一些内存才能以最佳方式工作,该内存由底层平台提供。在Java中,JVM提供了这些内存资源(当然需要操作系统授权)。Java中,JVM内存主要分为5个部分分别为:方法区、堆、栈、PC寄存器和本地方法区。

本文主要关注堆和栈。内存不像一张白纸,程序员只需要草草记下就可以存储数据,在使用内存之前,需要对其进行结构化。栈和堆是使用内存时遵循的数据结构,在程序执行期间,存储的数据用于各种目的,这取决于程序的目的是什么。

JVM决定程序执行期间使用的运行时数据区域。有些数据区域是依赖于JVM的,这意味着它们是在JVM启动时创建的,并在JVM的整个生命周期中持续存在。但是,每个线程都创建和销毁其他数据区域。JVM可以同时执行多个执行线程,这意味着每个线程都有自己的pc(Program Counter,程序计数器)来维护正在执行的当前指令的位置,还有一个栈帧来保存静态内存分配。

栈是内存中的一种结构,开发人员在其中存储元素,其方式允许只从栈顶检索数据——通常称为先入后出(FILO或LIFO)。因为每个线程都维护一个私有的JVM栈,它被用来存储与它们的静态内存分配相关的变量。特定于我们在代码中声明和使用的方法的原语变量实际上存储在栈区域中。另外,对实际存储在堆内存中的对象的引用也存储在堆栈区域中。因此,任何本地分配的内存都存储在堆栈中。

堆栈内存的默认大小可以使用JVM参数-Xss来更改。有时,如果分配了太多变量或方法递归调用自身,则堆栈可能溢出。所有Java程序员都知道的一个常见错误是Java.lang.stackoverflowerror,当栈内存不足时提示该错误。Java中的每个方法调用都会在栈中分配一块内存,因此,设计糟糕的递归方法调用很容易占用所有栈内存,导致栈内存溢出错误。

堆是JVM一启动就创建的内存区域,它会一直存在,直到JVM被销毁。与栈不同的是,栈是单个线程的属性(因为每个线程都有自己的栈),堆实际上是由JVM本身管理的全局内存,此内存在运行时用于为对象分配内存。因此,对象的实例化可以是用户定义的类、JDK或其他库类。简而言之,使用new关键字创建的任何对象都存储在堆内存中。堆内存中的对象可被JVM运行的所有线程访问。访问管理非常复杂,使用了非常复杂的算法,这就是JVM垃圾收集器发挥作用的地方。

堆的默认大小可以使用JVM参数-Xms-Xmx来更改。随着对象的创建和销毁,堆的大小也会增加或减少,如果达到最大内存限制后并尝试进一步分配内存,则抛出java.lang.OutOfMemoryError

堆中的字符串池(StringPool)

Java.lang.String类是Java中使用最多的类,因此,应该特别注意它的效率问题。与基本数据类型相比,字符串的操作效率总是很慢,所以,必须采用某种方式使得字符串对象操作的效率和便利性方面类似或者接近于基本数据类型,为了达到这个目的就在堆中分配了一块特殊内存区域(StringPool),创建的任何字符串对象都由JVM存储在StringPool中。与堆中创建的其他对象相比,这提高了性能。

从代码示例说明堆和栈

为了更好地说明在Java中堆和栈内存的使用,让我们写一个简单的程序,并决定哪个分配分配到哪个内存——堆或栈:

public class HeapAndStackTest {
    public static void main(String[] args) {
        int x=10;
        int y=20;
        String greet = "Hello";
        Date d = new Date();
        diff(x, y);
    }

    public static int diff(int x1, int x2) {
        return x2-x1;
    }
}

这段代码运行方式如下:

  • 程序启动,JVM将Java运行时环境(JRE)类加载到堆中。
  • 在遇到main() 方法时,会创建一个栈帧。
  • 局部变量xy存储在栈中。
  • 字符串greet分配在堆的StringPool区域中。
  • Date对象分配在堆区,而它的引用d存储在栈中。

Img

总结

栈和堆是Java程序在代码执行期间使用的两个区域。除了这两个之外,还有其他内存区域,如方法区域、寄存器、本地方法域等等。每种区域在Java应用程序中都有其特定的用途。但是,从程序员的角度来看,栈和堆是JVM必须理解的区域。

到此这篇关于浅谈一下Java中的堆和栈的文章就介绍到这了,更多相关Java的堆和栈内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

浅谈一下Java中的堆和栈

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

浅谈一下Java中的堆和栈

这篇文章主要介绍了一下Java中的堆和栈,Java数据类型在执行过程中存储在两种不同形式的内存中:栈和堆,它们通常由运行Java虚拟机(JVM)的底层平台维护,需要的朋友可以参考下
2023-05-18

浅谈Java数组的一些使用方法及堆栈存储

数组用于存储一组同一数据类型数据的容器数组会对放入其中的数据自动编号,编号是从0开始的---下标定义格式数据类型[] 数组名 = new 数据类型[数组的大小];---可以先声明再初始化int[] arr = new int[5];---定
2023-05-31

java中栈和堆的区别

在说堆和栈之前,我们先说一下JVM(虚拟机)内存的划分: (推荐学习:java课程)Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的。JVM运行时在内存中开辟一片内存区域,启动时在自己的内
java中栈和堆的区别
2021-03-03

浅谈一下Java中的悲观锁和乐观锁

这篇文章主要介绍了一下Java中的悲观锁和乐观锁,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-05-16

浅谈一下Java中枚举的用法

这篇文章主要介绍了浅谈一下Java中枚举的用法,枚举是一个被命名的整型常数的集合,用于声明一组带标识符的常数,当一个变量有几种固定可能的取值时,就可以将它定义为枚举类型,需要的朋友可以参考下
2023-05-14

Java中的栈和堆有什么用

在Java中,栈和堆都是用于内存管理的。1. 栈(Stack):栈是一种后进先出(LIFO)的数据结构,用于存储方法调用和局部变量。每个线程在运行时都会有一个独立的栈空间,用于保存方法调用时的参数、局部变量和返回地址等信息。当一个方法被调用
2023-08-16

Java中堆和栈的区别在哪

Java中堆和栈的区别主要以下几点:一、分配释放方式不同;二、功能作用不同;三、生命周期不同。栈是为编译器自动分配和释放的,如函数参数、局部变量、临时变量等等。堆是为成员分配和释放的,由程序员自己申请、自己释放。
Java中堆和栈的区别在哪
2023-10-29

浅谈一下forward和redirect的区别

这篇文章主要介绍了forward和redirect的区别,在前端开发中,有很多刚入行的朋友不了解这两者之间的区别,那么这篇文章可以带给你新的认知,需要的朋友可以参考下
2023-03-24

浅谈一下Java中集合的迭代方式

这篇文章主要介绍了浅谈一下Java中集合的迭代方式,可以帮助我们学习,理解函数式编程,需要的朋友可以参考下
2023-05-14

java中栈和堆的区别是什么

Java栈Java 栈总是和线程关联在一起,每当创建一个线程时,JVM就会为这个线程创建一个对应的Java栈,在这个Java栈中又会含有多个栈,这些栈帧是与每个方法关联起来的,每个运行一个方法就创建一个栈帧会含有一些“内部变量"(在方法内定义的变量)、"操作栈
java中栈和堆的区别是什么
2019-01-17

浅谈一下Python中的with用法

这篇文章主要介绍了浅谈一下Python中的with用法,有一些任务,可能事先需要设置,事后做清理工作。对于这种场景,Python的with语句提供了一种非常方便的处理方式,需要的朋友可以参考下
2023-05-15

浅谈一下Java的双亲委派模式

这篇文章主要介绍了一下Java的双亲委派模式,双亲委派指得是,JVM在加载类时,会委派给ExtClassLoader和BootstrapClassLoader进⾏加载,如果没加载到才由⾃⼰进⾏加载,需要的朋友可以参考下
2023-05-18

Java中的堆、栈和常量池怎么理解

这篇文章主要讲解了“Java中的堆、栈和常量池怎么理解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java中的堆、栈和常量池怎么理解”吧!1.寄存器最快的存储区, 由编译器根据需求进行分配
2023-06-17

浅谈一下Java中的访问修饰符以及作用

这篇文章主要介绍了浅谈一下Java中的访问修饰符以及作用,修饰符修饰的是“被访问”的权限,所有修饰符都可以修饰成员变量,方法,构造方法,需要的朋友可以参考下
2023-05-19

浅谈一下Vue生命周期中mounted和created的区别

每一个vue实例从创建到销毁的过程,就是这个vue实例的生命周期,在这个过程中,他经历了从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程,那么这些过程中,具体vue做了些啥,我们今天来了解一下
2023-05-19

浅谈Java中static和非static的区别

关于static和非static变量的区别1. static 修饰的变量称为类变量或全局变量或成员变量,在类被加载的时候成员变量即被初始化,与类关联,只要类存在,static变量就存在。非static修饰的成员变量是在对象new出来的时候划
2023-05-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录