【Java】Java 中的栈和堆内存

news2024/11/14 14:23:33

本文仅供学习参考!
相关教程地址:
https://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html
https://www.developer.com/java/stack-heap-java-memory/
https://zhuanlan.zhihu.com/p/529280783

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

Java 平台如何工作?

Java程序运行在Java虚拟机(JVM)提供的平台上。该平台是提供java应用程序运行时所需的所有资源的管理器。这意味着开发人员编写的程序(或我们创建的应用程序)无法直接访问系统资源(无论是硬件还是软件),除非其运行的平台提供了它。对于 Java,顺序如下:

Java 虚拟机 (JVM) 教程

JVM 层使 Java 平台变得独立。其他编程语言,如 C/C++,不使用这样的层,因此,尽管它们是可移植的,但它们本身并不独立于平台:

Java虚拟机教程

这两种情况都有很多优点和缺点。由于 Java 语言和 JVM 平台的开发由同一组人员参与,因此对程序员便利性的偏向是显而易见的。这导致了巨大的演变;从一门语言开始,如今 Java 已经成为一个自己的生态系统。同时,像 C/C++ 这样的编程语言通过能够直接访问系统资源,更加注重核心单元的最佳使用,从而产生超快速和高效的程序。但两者在软件开发领域都有其用途。

对于一般语言来说,所有编程语言在编译和执行过程中都有许多相似之处。这些领域中最重要的领域之一是内存管理。无论使用哪种语言,内存管理都会对程序的整体效率产生重大影响,因为它有助于管理内存资源,从而提高应用程序性能。使用的内存越多,程序速度就越慢。

Java 中的运行时内存是什么?

应用程序中的一个常见现象是每个应用程序都需要一些内存才能以最佳方式工作。该内存由底层平台提供。对于 Java,JVM 提供了它(当然,这是由操作系统授予的)。JVM内存典型的五个部分包括:方法区PC寄存器本机内存

现在让我们重点关注堆栈和堆部分。内存不像一张白纸,程序员只需记下数据即可存储数据。相反,内存需要在使用之前进行结构化。栈和堆是使用内存时遵循的数据结构。在程序执行期间,存储的数据用于各种目的,具体取决于程序的目的。

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

Java 中的堆栈内存是什么?

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

可以使用 JVM 参数**-Xss更改堆栈内存的默认大小。有时,如果分配太多变量或方法递归调用自身,堆栈可能会溢出。所有 Java 程序员都知道的一个常见错误是java.lang.StackOverFlowError**。当堆栈已满时,会弹出此错误。Java 中的每个方法调用都会在堆栈中创建一个新块。因此,设计不当的递归方法调用很容易耗尽所有堆栈,从而导致溢出错误。

Java中的堆内存是什么

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

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

Java堆字符串池

值得注意的是,尽管它是一个类,但对于java.lang.String,从该类实例化的任何对象的处理方式都不同。JVM 创建者发现这是 Java 编程中最常用的类。因此,应特别注意保持其效率。此外,与原始类型相比,字符串操作总是很慢。因此,魔法必须存在,以便字符串对象的使用与使用基本类型类似或接近它在代码中的效率和便利性。因此,为了保持 JVM 提供的效率,使用了堆内称为StringPool的特殊内存区域。创建的任何字符串对象都存储在StringPool中由 JVM 执行。与堆中创建的其他对象相比,这提高了性能。

Java 堆和堆栈代码示例

为了更好地说明 Java 中堆和栈内存的使用,让我们编写一个简单的程序并决定哪个分配分配给哪个内存 - 堆还是栈:

package project1;
import java.util.Date;
public class Main{
    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;
    }
}

此示例 Java 代码按以下方式工作:

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

Java教程

END

栈和堆是Java程序在代码执行过程中使用的两个区域。除了这两个之外,还有其他内存区域,例如方法区寄存器本机区等。每个在 Java 应用程序中都有其特定的用途。但是,从开发者的角度来看,栈和堆是必须了解的 JVM 的基本方面。然而,对所有运行时内存规范的透彻理解始终是一个优势,并且将成为未来 Java 编程教程的主题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/693459.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HOT24-回文链表

leetcode原题链接:回文链表 题目描述 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。 示例 1: 输入:head [1,2,2,1] 输出&#xff1a…

Leetcode 刷题 动态规划

198. 打家劫舍 1. 确定dp数组(dp table)以及下标的含义 dp[i]:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i] 2. 确定递推公式 dp[i] max(dp[i - 2] nums[i], dp[i - 1]); 3. dp数组如何初始…

分类预测 | MATLAB实现GA-BiLSTM遗传算法优化双向长短期记忆网络的数据多输入分类预测

分类预测 | MATLAB实现GA-BiLSTM遗传算法优化双向长短期记忆网络的数据多输入分类预测 目录 分类预测 | MATLAB实现GA-BiLSTM遗传算法优化双向长短期记忆网络的数据多输入分类预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 MATLAB实现GA-BiLSTM遗传算法优化双向长短…

【数据库】MySQL慢查询常用分析方法

系统慢慢越来越卡了,怎么定位系统慢的原因,大部分是因为服务器资源占用耗费高引起的,如CPU,内存和带宽等等。MySQL在日常开发工作中可能会遇到某个新功能在测试时需要很久才返回结果,这时就应该分析是不是慢查询导致的…

【javascript】2048小游戏

目录 什么是2048 游戏状态机 游戏界面绘制 3.1 界面 3.2 数字的背景颜色 分数逻辑 4.1 加分 4.2 更新最高分 方向控制逻辑 5.1 数组 5.2 随机数 5.3 初始化 5.4 判断数组是否全部填满 5.5 判断方格是否还能移动 5.6 上下左右的监听事件 5.7 移动 完整代码 …

微服务划分的姿势

我们知道微服务是一种理念,没有确切的定义和边界,好比设计原则,是属于抽象的概念。在定义不明确的情况下谈划分也是一种各说各话,具体问题需要具体分析,所以这篇文章谈到的划分也不是绝对标准,仅供参考。 有…

final, finally和finalize的区别

final、finally和finalize是Java中用于异常处理的关键字。每个关键字都有不同的功能。final是一个访问修饰符,finally是异常处理中的代码块,而finalize是Object类的方法。 除此之外,final、finally和finalize之间还存在许多区别。下面是final…

netty学习(1):1个客户端与服务器通信

1. 新建maven工程&#xff0c;添加netty依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"…

Avoid adding reactive properties to a Vue instance or its root $da

避免在运行时向Vue实例或其根$data添加反应性属性-在数据选项中预先声明它。 在页面中声明对象&#xff0c;直接修改即可。 data(){return{addressInfo:{}}}

阿里云服务器地域可用区怎么选?

阿里云服务器地域和可用区怎么选择&#xff1f;地域是指云服务器所在物理数据中心的位置&#xff0c;地域选择就近选择&#xff0c;访客距离地域所在城市越近网络延迟越低&#xff0c;速度就越快&#xff1b;可用区是指同一个地域下&#xff0c;网络和电力相互独立的区域&#…

如何在Mac上安装 Stable Diffusion 来创作

​ 看着别人玩&#xff0c;是不是特想自己搭建一个&#xff0c;那么现在教程来了。 玩这种需要算力的东西&#xff0c;电脑配置肯定是越高越好了。我的电脑配置如下&#xff1a;​ 接下来就开始安装了。 第一步&#xff1a;安装homebrew 打开terminal终端&#xff08;comma…

使用maven中的profile动态打包不同环境的配置文件

maven中的profile可以在打包时动态选择不同的配置文件进行打入&#xff0c;在项目具有开发、测试、生产环境时可以更方便优雅的进行不同环境的打包运行 示例图&#xff1a; 1-配置profile 第一步需要为每个环境配置一个profile标签&#xff0c;在pom文件中进行配置。我这里只…

如何做好工程英语翻译

近年来&#xff0c;随着全球经济的持续发展&#xff0c;涉外工程业务日益增多&#xff0c;工程英语翻译的需求也越来越大。那么&#xff0c;工程英语翻译难吗&#xff0c;如何做好工程英语翻译&#xff0c;服务好的北京翻译公司哪里有&#xff1f; 据了解&#xff0c;工程英语语…

macOS Ventura 13.4.1With OpenCore 0.9.3 and winPE双引导黑苹果镜像

镜像特点 完全由黑果魏叔官方制作&#xff0c;针对各种机型进行默认配置&#xff0c;让黑苹果安装不再困难。系统镜像设置为双引导分区&#xff0c;全面去除clover引导分区&#xff08;如有需要&#xff0c;可以自行直接替换opencore分区文件为clover引导文件&#xff09;备注…

知识蒸馏学习记录(二)

上一篇博文中我们介绍了知识蒸馏的一些基础知识&#xff0c;这里我们来学习其到底是如何完成知识蒸馏过程的。 知识蒸馏为何可以让学生网络模型小却性能强&#xff1f; 详细很多同学与我有相同的疑问&#xff0c;尽管它依靠不同的蒸馏温度T可以学得一些hard target标注无法包…

《计算机系统与网络安全》 第四章 密码学基础

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

8--Gradle进阶 - Gradle任务的入门、任务行为

8--Gradle进阶 - Gradle任务的入门、任务行为 Gradle Task Gradle 项目工程的管理 实质上是 Task 对象的集合。一个 Task 表示一个逻辑上较为独立的执行过程&#xff0c;比如编译Java 源代码&#xff0c;拷贝文件&#xff0c; 打包Jar 文件&#xff0c;甚至可以是执行一个系统命…

flutter Exception: Gradle task assembleDebug failed with exit code 1

Exception: Gradle task assembleDebug failed with exit code 1 解决方案&#xff1a; 出现这个问题&#xff0c;可能是依赖的插件无法下载 找到项目的android->build.gradle, 将 google() mavenCentral()改成 maven{url https://maven.aliyun.com/repository/google }m…

XML的运用(XML解析)

一、XML文件的三种配置位置机读取方式 Java中配置XML文件的三种配置位置机读取方式&#xff1a;常用的三种 1、同包下 在演式之前我们把前期演示的部分给准备好&#xff1a; 我们以properties为后缀的文本为例&#xff1a; unamemybatis_ssm upassxiaoli urljdbc:mysql://lo…

短视频矩阵-短视频seo源码开发搭建

开发场景&#xff1a;抖音seo&#xff0c;短视频seo&#xff0c;抖音矩阵&#xff0c;短视频矩阵源码开源 一、 短视频矩阵源码需要掌握以下技术&#xff1a; 1. 视频编码技术 短视频矩阵系统利用视频编码技术&#xff0c;将视频文件进行压缩和解压缩&#xff0c;实现了高质…