0

0

理解 Java 内存模型:堆和栈解释

霞舞

霞舞

发布时间:2024-11-24 09:21:01

|

836人浏览过

|

来源于dev.to

转载

理解 java 内存模型:堆和栈解释

了解 java 如何处理按值传递和按引用传递后,下一步是更深入地研究 java 的内存模型。具体来说,我们将探讨堆和栈——java 内存管理的两个关键组件。清楚地理解这些概念将帮助您编写高效的代码。

java中的堆和栈是什么?

在java中,程序使用的内存分为两个主要区域:

1.堆内存:用于对象和类实例的动态分配。

2.stack memory:用于存储方法调用细节、局部变量和引用。

立即学习Java免费学习笔记(深入)”;

堆内存:动态内存池

  • 用途:堆是存储所有对象及其实例变量(字段)的地方。
  • 特点: 由所有线程共享。对象保留在堆中,直到不再被引用为止,此时它们就有资格进行垃圾回收。在运行时分配。
  • 用法示例: 使用 new 关键字创建的任何对象都驻留在堆中。

堆栈内存:执行上下文

  • 用途:堆栈用于管理方法执行和局部变量(原语和对象引用)。​​
  • 特点: 每个线程都有自己的堆栈(线程本地内存)。遵循后进先出 (lifo) 原则。当方法被调用和返回时自动分配和释放。
  • 用法示例: 方法调用、局部变量和对象引用都存储在堆栈中。

堆与堆栈:主要区别

feature stack heap
storage method calls, local variables objects and instance variables
access lifo (fast) dynamic access (slower)
thread ownership thread-local shared across all threads
lifetime limited to method execution exists until garbage collected
size smaller and fixed larger and grows dynamically
management automatically managed managed by garbage collector

堆和栈如何协同工作

要了解堆和堆栈如何交互,让我们回顾一下按值传递和按引用传递:

  1. 原始类型: 直接存储在栈中。 作为副本按值传递。
  2. 对象参考: 引用(内存地址)存储在堆栈中。 实际的对象存储在堆中。 当传递给方法时,引用被复制,但它仍然指向同一个堆对象。

代码示例:实际的堆和栈

让我们分析一个简单的程序来了解堆和堆栈内存是如何使用的。

class person {
    string name;

    person(string name) {
        this.name = name;
    }
}

public class heapstackexample {
    public static void main(string[] args) {
        int number = 10; // stored in the stack
        person person = new person("alice"); // reference in stack, object in heap

        system.out.println("before: " + person.name); // output: alice
        modifyperson(person);
        system.out.println("after: " + person.name); // output: bob
    }

    public static void modifyperson(person p) {
        p.name = "bob"; // modifies the object in the heap
    }
}

内存崩溃:

Codiga
Codiga

可自定义的静态代码分析检测工具

下载
  • 堆栈内存:
    • number:直接存储在栈中。
    • person:存储在栈中的引用,指向堆中的person对象。
    • p:人员引用的副本,也存储在堆栈中。
  • 堆内存:
    • 一个具有名称字段的 person 对象(最初为“alice”,修改后为“bob”)。

方法调用如何影响堆栈

调用方法时:

  • 创建一个新的堆栈帧来存储:
    • 方法参数。
    • 局部变量。
    • 实例方法对当前对象(this)的引用。
  • 当该方法返回时,其堆栈帧将被删除,从而释放内存。

这是一个例子:

public class stackdemo {
    public static void main(string[] args) {
        int result = calculate(5); // call method, push stack frame
        system.out.println(result); // output: 25
    }

    public static int calculate(int n) {
        return n * n; // stack frame includes 'n'
    }
}

内存使用情况:

  • main方法为自己创建一个栈帧。
  • 当调用calculate(5)时,会推送一个新的堆栈帧。
  • 计算完成后,其框架将弹出,并释放内存。

堆和堆栈的常见问题

  • stackoverflowerror:
    当堆栈内存不足时发生,通常是由于深度递归或无限方法调用。

  • 示例:

public class stackoverflowexample {
    public static void recursivemethod() {
        recursivemethod(); // infinite recursion
    }

    public static void main(string[] args) {
        recursivemethod();
    }
}

  • 内存不足错误:堆空间:
    当堆已满且无法为新对象分配更多内存时发生。

  • 示例:

import java.util.ArrayList;

public class HeapOverflowExample {
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();
        while (true) {
            list.add(new int[100000]); // Keep allocating memory
        }
    }
}

优化堆和堆栈的使用

堆:

  • 仅在必要时使用对象。
  • 对昂贵或重复的对象使用对象池。
  • 避免创建不必要的引用,从而阻止垃圾回收。

堆:

  • 避免深度递归。
  • 使用有效的算法来减少方法调用的次数。

要点

  • 堆和栈一起工作:
    • 对象存储在堆中,而引用和局部变量存储在堆栈中。
  • 堆栈更快但有限:
    • 它会随着方法调用而自动增大和缩小。
    • 专为临时、线程本地数据而设计。
  • 堆更大但共享:
    • 用于需要在单个方法调用之外保留的对象。
    • 由垃圾收集器管理。
  • 了解限制:
    • 通过受控递归避免堆栈溢出
    • 优化对象创建以避免堆内存问题。

深入了解 java 中堆和栈内存的工作原理,您将能够更好地编写高效、无错误的程序,并了解 java 如何在幕后管理内存。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

832

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

738

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

734

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

397

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16925

2023.08.03

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

36

2026.01.14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
SQL 教程
SQL 教程

共61课时 | 3.4万人学习

10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号