- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
博客:https://www.emanjusaka.com 博客园:https://www.cnblogs.com/emanjusaka 公众号:emanjusaka的编程栈 。
by emanjusaka from https://www.emanjusaka.com/archives/java-heap-stack-distribution-feature 本文为原创文章,可能会更新知识点以及修正文中的一些错误,全文转载请保留原文地址,避免产生因未即时修正导致的误导.
经常有人把 Java 内存区域笼统地划分为堆内存(Heap)和栈内存(Stack),这种划分方式直接继承自传统的 C、C++程序的内存布局结构,在 Java 语言就显得有些粗糙了,实际的内存区域划分是要更复杂一下。如下所示:
方法区、堆是由所有线程共享的数据区。虚拟机栈、本地方法栈和程序计数器是线程隔离的数据区.
我们最关注的、与对象内存分配关系最密切的区域是“堆”和“栈”两块。其中“栈”通常就是指这里的虚拟机栈,更多情况下只是指虚拟机栈中局部变量表部分。下面我们详细分析一下堆内存和栈内存的数据分布.
如果你擅长 Java 这种内存自动管理的语言,这个问题很好回答.
栈上的数据:
基本数据类型(boolean、byte、char、short、int、float、long、double) 。
对象引用(reference 类型,它并不等同于对象本身,可能是一个指向对象起始地址的应用指针,也可能是指向一个代表对象的句柄或者其他与此对象相关的位置) 。
returnAddress 类型(指向了一条字节码指令的地址) 。
堆上数据:
普通对象:各种类的实例.
数组:数组是一种特殊类型的对象,可以存储多个相同类型的元素.
基本类型包装器对象:Java 提供了一些基本类型的包装器类:如 Integer、Double、Character 等.
我们先来分析下程序中的栈和堆,然后总结出它们的特点.
栈的数据结构特点是先进后出。由于这个特点,非常适合记录程序的函数调用,也称为函数调用栈。函数调用栈从下到上增长,每当函数执行时,就会在栈顶部分分配一块连续的内存,称为帧。这个帧存储了当前函数的通用寄存器和当前函数的局部变量的上下文信息。下面给出一个简单的 Java 函数调用,我们分析一下这个过程:
public class StackExample { public static void main(String[] args) { int result = add(3, 5); System.out.println("结果是: " + result); } public static int add(int a, int b) { return a + b; } } 在这个例子中,`main`函数调用了`add`函数。当`main`函数开始执行时,会在栈内存中为`main`函数分配一块空间,包括局部变量`result`和参数`args`。然后,`main`函数调用`add`函数,此时会在栈内存中为`add`函数分配另一块空间,包括局部变量`a`、`b`和返回地址。当`add`函数执行完毕后,其占用的栈空间会被释放,控制权返回给`main`函数。最后,`main`函数执行完毕,整个程序结束。 通常情况下,它需要连续的内存空间,这意味着程序在调用下一个函数之前必须知道下一个函数需要多少内存空间。但是程序是怎样知道的呢? 答案是编译器为我们完成了这一切。当编译代码时,函数是一个最小的编译单位。每当编译器遇到一个函数时,它就知道当前函数使用寄存器和局部变量所需的空间。 因此,无法在编译时确定大小或可以更改大小的数据是不能安全地放置在栈上的。 ### Heap 有些数据不能安全地放在栈上,所以最好放在堆上,比如下面的ArrayList: ```java import java.util.ArrayList; public class VariableLengthArrayExample { public static void main(String[] args) { // 创建一个空的 ArrayList ArrayList arrayList = new ArrayList<>(); // 向 ArrayList 中添加元素 arrayList.add(1); arrayList.add(2); arrayList.add(3); // 输出 ArrayList 的大小 System.out.println("Size of the ArrayList: " + arrayList.size()); // 访问 ArrayList 中的元素 for (int i = 0; i < arrayList.size(); i++) { System.out.println("Element at index " + i + ": " + arrayList.get(i)); } // 删除 ArrayList 中的一个元素 arrayList.remove(1); // 再次输出 ArrayList 的大小和内容 System.out.println("Size of the ArrayList after removal: " + arrayList.size()); for (int i = 0; i < arrayList.size(); i++) { System.out.println("Element at index " + i + ": " + arrayList.get(i)); } } }
当创建一个ArrayList 时,程序需要动态的分配内存。如果数组的实际使用量超过了这个容量,程序会分配一个更大的内存块,将现有元素复制到其中,添加新元素,然后释放旧内存。此过程允许数组根据需要动态调整大小。请求系统调用并找到新的内存然后一一复制的过程是非常低效的。所以这里最好的做法是提前预留需要的空间.
另外,需要跨栈引用的内存也需要放在堆上,这很好理解,因为一旦一个栈帧被回收,其内部的局部变量也会被回收,所以在不同的调用栈中共享数据只能使用堆.
栈上存储的数据是静态的,大小固定,生命周期固定,线程隔离不能跨栈引用.
堆上存储的数据是动态的、不固定大小、不固定生命周期、线程共享可以跨栈引用.
谦学于心,谷纳万物,静思致远,共筑收获之旅! 原文地址: https://www.emanjusaka.com/archives/java-heap-stack-distribution-feature 微信公众号:emanjusaka的编程栈 。
最后此篇关于Java中堆内存和栈内存上的数据分布和特点的文章就讲到这里了,如果你想了解更多关于Java中堆内存和栈内存上的数据分布和特点的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
Câu hỏi dành cho người mới bắt đầu sử dụng Android. Được rồi, tôi đã ghi thành công vào tập tin. Ví dụ. //Lấy tên tệp String filename = getResources().getString(R.string.filename
Tôi đã lưu cùng một hình ảnh vào /data/data/mypackage/img/ và bây giờ tôi muốn hiển thị toàn màn hình này, tôi đã thử sử dụng ACTION_VIEW để hiển thị ứng dụng chuẩn Android nhưng nó không hiển thị hình ảnh từ /data/data/mypackage/img/
Tôi đang sử dụng Xcode 9, Swift 4. Tôi đang cố gắng hiển thị một hình ảnh trong ImageView từ một URL bằng cách sử dụng mã sau: func getImageFromUrl(sourceUrl: String) -> UII
Tôi gặp sự cố khi cài đặt genymotion trên Ubuntu. Chủ yếu là tôi không thể gỡ lỗi cơ sở dữ liệu của mình vì tôi không thể thấy nội dung của thư mục /data/ thông qua DBMS trong eclipse hay thông qua adb trong shell. Không hiển thị
Tôi đang cố gắng đăng một số dữ liệu JSON bằng PHP. Nhưng có điều gì đó không ổn. Đây là html của tôi -- {% cho x trong tập hợp %}
Tôi nhận thấy kết quả khác nhau từ cả hai cách tiếp cận. Tại sao lại như vậy? Tôi biết những gì đang xảy ra trên lm nhưng không thể hiểu được những gì đang xảy ra trên tslm. > thư viện(dự báo) > set.seed(2) > tts lm(t
Tôi không chắc tại sao điều này lại xảy ra! Tôi có một lớp được spring data elasticsearch và spring data jpa sử dụng nhưng tôi gặp lỗi khi thử chạy ứng dụng của mình. Lỗi khi tạo
Trong biểu đồ vega này, nếu tôi tải xuống và chuyển đổi flare-dependencies.json bằng lệnh jq sang csv sau, jq -r '(map(keys) | add | unique) as
Tôi đang nộp một dự án trong đó tôi phải tạo một cơ sở dữ liệu mysql có chứa một bảng. Mọi thứ đều ổn nên tôi chỉ muốn kiểm tra xem làm thế nào để gửi tất cả các tệp nén của mình cho người khác sử dụng máy tính khác. Về cơ bản, làm thế nào để tôi tạo tệp cơ sở dữ liệu của mình cho một máy tính khác,
Tôi có một ứng dụng ghi các tập tin văn bản vào bộ nhớ trong. Tôi muốn xem xét kỹ hơn máy tính của mình. Tôi chạy Toast.makeText để hiển thị đường dẫn và nó ghi: /data/data/my-package nhưng khi tôi vào An của Android Studio
Tôi thích cách trình giả lập Genymotion tải Android với tốc độ đáng kinh ngạc như vậy. Tốc độ rất tốt, nhưng hiệu suất vẫn còn đôi chút chập chờn. Cách truy cập trình giả lập Genymotion từ File Explorer trong Eclipse
Tôi cần thay đổi định dạng của hộp văn bản trong Silverlight. Dữ liệu được liên kết thông qua MVVM. Ví dụ, có một thuộc tính int và tôi thêm 1 vào giá trị trong bộ thiết lập và gọi OnPropertyChanged
Tôi muốn gửi yêu cầu tới Youtube Data API, nhưng tôi không cần truy cập vào bất kỳ thông tin người dùng nào. Tôi chỉ muốn duyệt các video công khai và hiển thị video dựa trên một thuật ngữ tìm kiếm. Tôi có thể làm điều này mà không cần sự cho phép không? Câu trả lời hay nhất YouTube
Tôi đã thiết lập ứng dụng Twilio và muốn gửi thông tin cập nhật cho mọi người nhưng không muốn trả lời từng tin nhắn riêng lẻ. Tôi chỉ muốn họ gọi điện nếu họ gặp vấn đề. Mọi thứ đều hoạt động tốt nhưng tôi muốn hiển thị văn bản đến khi tôi gửi để đảm bảo không bỏ sót bất kỳ vấn đề nào. Tôi đang sử dụng p
Tôi có một trang web có biểu mẫu (hiện tại là HTML thuần túy, nhưng chúng tôi đang chuyển sang JQuery). Luồng như sau: Lấy dữ liệu đầu vào của người dùng --- 5 số nguyên Gọi dịch vụ web qua REST Chạy một số phép tính ở phía máy chủ... và tạo ra
Giả sử chúng ta có một tệp có tên là configuration.js và khi chúng ta nhìn vào bên trong, chúng ta thấy: 'use strict'; var profile = { "project": "%Projec
Đây là một phần mở rộng của Câu hỏi trước: Bây giờ tôi có thể trả về dữ liệu JSON thành công từ Bộ điều khiển CI của mình, nó trả về: {"results":[{"id":"1","Sourc
Có cách nào hiệu quả để xóa toàn bộ dung lượng lưu trữ tài liệu của CBL trong iOS không? Tôi có thắc mắc về vấn đề này hoặc nếu ai đó biết cách làm cho ứng dụng hoạt động như thể nó vừa được cài đặt thì sẽ rất hữu ích. Chúng tôi đang làm việc để đảm bảo rằng việc đăng xuất của chúng tôi thực sự thiết lập ứng dụng thành
Tôi có một ứng dụng Rails giao tiếp với các ứng dụng Rails khác để chèn dữ liệu. Tôi đang sử dụng phương thức jQuery $.post để chèn dữ liệu. Ứng dụng Rails khác của tôi hiển thị 200 OK cho phần chèn. Nhưng trong
Tôi đang chạy thử nghiệm đơn vị cho lệnh gọi API phục vụ yêu cầu đăng bài. Tôi đang chuyển nội dung yêu cầu và phải trả về phản hồi dưới dạng dữ liệu tài khoản. Nhưng tôi chỉ nhận được lỗi khẳng định Lưu ý: Dữ liệu được lấy từ Azure spec.js const accou
Tôi là một lập trình viên xuất sắc, rất giỏi!