Java虚拟机(JVM):内存区域

一、内存区域介绍

Java虚拟机(JVM)内存可以分为以下几个区域:

  1. 程序计数器(Program Counter Register):用于记录当前线程执行的字节码指令的地址,属于线程私有的区域。在任意时刻,一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器就是用来记录当前线程执行的方法字节码的指令地址,当线程执行Java方法时,程序计数器记录的是正在执行的虚拟机字节码指令的地址;当线程执行Native方法时,程序计数器的值为空(Undefined)。
  2. Java虚拟机栈(Java Virtual Machine Stacks):也是线程私有的区域,每个线程在创建时都会创建一个栈,用于存储方法的局部变量、操作数栈、动态链接、方法出口等信息。每个方法在执行时都会创建一个栈帧,用于存储方法的局部变量和部分运算结果。栈帧随着方法的进入和退出而有入栈和出栈的操作。如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态扩展,但无法申请到足够的内存时,将抛出OutOfMemoryError异常。
  3. 本地方法栈(Native Method Stacks):与虚拟机栈类似,但是用于执行Native方法。
  4. 堆(Heap):为所有线程共享的区域,用于存储对象实例。Java堆是Java虚拟机管理的最大的一块内存区域,也是垃圾回收器管理的主要区域。在虚拟机启动时创建,用于存储各种对象(包括实例对象和数组)。
  5. 方法区(Method Area):也是所有线程共享的区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。方法区在虚拟机启动时创建,存储了每个类的结构信息,包括运行时常量池、字段和方法数据、构造函数和类方法等。
  6. 运行时常量池(Runtime Constant Pool):是方法区的一部分,用于存放编译期生成的各种字面量和符号引用。运行时常量池具有动态性,可以在运行时进行扩充。
  7. 直接内存(Direct Memory):不是虚拟机运行时数据区的一部分,但是也被频繁地使用。在JDK 1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。这样可以在一些场景中显著提高性能。 这些区域共同组成了Java虚拟机的内存布局,每个区域都有其特定的作用和用途,用于支持Java程序的正常执行和内存管理。

二、代码分析 

代码段一:

public class MemoryExample {// 静态变量-存储在方法区private static String staticVariable = "Hello, World!";// 实例变量-存储在堆中private String instanceVariable;public void method() {// 局部变量-存储在栈中int localVar = 10;System.out.println(localVar);// 对象实例化-对象存储在堆中,变量存储在栈中MemoryExample obj = new MemoryExample();obj.instanceVariable = "Java Memory";}public static void main(String[] args) {method(); // 静态方法调用-存储在栈中// 程序计数器-记录当前线程执行的字节码指令的地址int pc = 0;// 垃圾回收器对堆进行内存回收和分配Object obj = new Object();obj = null;System.gc();// 本地方法栈-存储本地方法的信息nativeMethod();}// 本地方法-不在Java虚拟机中执行,而是在本地操作系统中执行private static native void nativeMethod();
}

上述代码中,静态变量 staticVariable 存储在方法区,实例变量 instanceVariable 存储在堆中,局部变量 localVar 存储在栈中。静态方法 main() 存储在栈中,程序计数器记录当前线程执行的指令地址。 代码中还展示了对象的实例化,对象存储在堆中,变量存储在栈中。示例中的 MemoryExample obj = new MemoryExample(); 在堆中创建了一个对象实例,并将其引用存储在栈中的变量 obj 中。 此外,示例中还包含了对垃圾回收器的调用 System.gc(),用于对堆进行内存回收和分配。还展示了本地方法 nativeMethod(),它不在Java虚拟机中执行,而是在本地操作系统中执行,相关信息存储在本地方法栈中。

对于这个代码示例中的私有静态变量 staticVariable,实际上,它的初始化值 "Hello, World!" 也会存储在运行时常量池中。 在Java中,字符串常量字面量会被存储在运行时常量池中。当一个类被加载到内存中时,它的静态变量也会被初始化。对于字符串类型的静态变量,如果其初始化值是一个字符串常量字面量,那么该字符串常量字面量也会被存储在运行时常量池中。 因此,在代码示例中,初始化值 "Hello, World!" 会被存储在运行时常量池中。而静态变量 staticVariable 则是存储在方法区中,它持有对运行时常量池中 "Hello, World!" 字符串常量的引用。 需要注意的是,虽然 staticVariable 的值是一个字符串常量,它并不是直接存储在运行时常量池中,而是存储在方法区中的静态变量区域,并且该变量在运行时常量池中引用了对应的字符串常量。

代码段二:

public class MemoryExample {public static void main(String[] args) {// 字符串常量存储在运行时常量池中String str1 = "Hello";String str2 = "World";String str3 = str1 + str2; // 字符串拼接会在运行时常量池中创建新的字符串对象System.out.println(str3);// 类的全限定名存储在运行时常量池中String className = MemoryExample.class.getName();System.out.println(className);// 常量引用存储在运行时常量池中final int constantValue = 10;System.out.println(constantValue);}
}

在上述代码中,字符串常量 "Hello""World" 存储在运行时常量池中。通过字符串拼接操作 str1 + str2,会在运行时常量池中创建新的字符串对象 "HelloWorld"。类的全限定名 MemoryExample.class.getName() 也会存储在运行时常量池中。最后,常量引用 constantValue 的值 10 也会存储在运行时常量池中。 尽管代码示例中没有直接访问运行时常量池,但编译器和虚拟机会自动处理和使用运行时常量池中的数据,以满足程序的运行需求。

在代码示例中,字符串常量 "Hello" 存储在运行时常量池中,而变量 str1 存储在栈中,它持有对运行时常量池中字符串常量 "Hello" 的引用。 当代码执行到 String str1 = "Hello"; 这一行时,会先在运行时常量池中查找是否存在字符串常量 "Hello"。如果存在,那么变量 str1 就会直接引用该字符串常量;如果不存在,那么会在常量池中创建一个新的字符串常量 "Hello",然后变量 str1 引用这个新创建的字符串常量。 所以,变量 str1 存储在栈中,它的值是对运行时常量池中字符串常量 "Hello" 的引用。而字符串常量 "Hello" 存储在运行时常量池中,它的值是字符串的实际内容。

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

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

相关文章

分析商务报表使用什么工具?

传统的BI分析商务报表存在的问题 随着数字化转型的深入推进,企业面临着海量数据的挑战和机遇。数据是企业的重要资产,能够帮助企业洞察市场动态、优化业务流程、提升客户满意度、创造竞争优势。然而,传统的BI(商业智能&#xff0…

LVS - DR

LVS-DR 数据流向 客户端发送请求到 Director Server(负载均衡器),请求的数据报文(源 IP 是 CIP,目标 IP 是 VIP)到达内核空间。Director Server 和 Real Server 在同一个网络中,数据通过二层数据链路层来传…

Harvard transformer NLP 模型 openNMT 简介入门

项目网址: OpenNMT - Open-Source Neural Machine Translation logo: 一,从应用的层面先跑通 Harvard transformer GitHub - harvardnlp/annotated-transformer: An annotated implementation of the Transformer paper. ​git clone https…

【C++小项目】实现一个日期计算器

目录 Ⅰ. 引入 Ⅱ. 列轮廓 Ⅲ. 功能的实现 构造函数 Print 判断是否相等 | ! ➡️: ➡️!: 判断大小 > | > | < | < ➡️>&#xff1a; ➡️<&#xff1a; ➡️>&#xff1a; ➡️<&#xff1a; 加减天数 | | - | - ➡️&#xff1a;…

CSDN编程题-每日一练(2023-08-24)

CSDN编程题-每日一练(2023-08-24) 一、题目名称:计算公式二、题目名称:蛇形矩阵三、题目名称:小玉家的电费一、题目名称:计算公式 时间限制:1000ms内存限制:256M 题目描述: 给定整数n。 计算公式: n i-1 ∑ ∑ [gcd(i + j, i - j) = 1] i=1 j=1 输入描述: 输入整数n…

Rust 基础入门 ——所有权 引言 :垃圾自动回收机制的缺陷。

在以往&#xff0c;内存安全几乎都是通过 GC 的方式实现&#xff0c;但是 GC 会引来性能、内存占用以及 Stop the world 等问题&#xff0c;在高性能场景和系统编程上是不可接受的&#xff0c; 我们先介绍一下这些概念都是什么&#xff1a; 内存安全是指程序在运行过程中不会访…

【C# 基础精讲】LINQ 基础

LINQ&#xff08;Language Integrated Query&#xff09;是一项强大的C#语言特性&#xff0c;它使数据查询和操作变得更加简洁、灵活和可读性强。通过使用LINQ&#xff0c;您可以使用类似SQL的语法来查询各种数据源&#xff0c;如集合、数组、数据库等。本文将介绍LINQ的基础概…

简历考察点2_《CiCi-基于Vue3.0的智能音乐分享平台》

&#xff08;1&#xff09;项目初始化和推荐页面开发&#xff1a; 重点&#xff1a;轮播图、Scroll、下拉加载方法实现、 问题一&#xff1a;轮播图实现 ① 获取轮播图数据&#xff1a;虽然找到接口了&#xff0c;但是由于XHR请求在浏览器端会有跨域的限制&#xff0c;不能直…

2023 百度翻译 爬虫 js逆向 代码

js代码&#xff1a; const jsdom require("jsdom"); const {JSDOM} jsdom; const dom new JSDOM(<!DOCTYPE html><p>Hello world</p>); window dom.window; document window.document; XMLHttpRequest window.XMLHttpRequest;function n(t,…

【Java】树结构SQL数据的如何去实现搜索

这里写自定义目录标题 需要实现的效果前端需要的json格式&#xff1a;一定是一个完整的树结构错误错误的返回格式错误的返回格式实现的效果 正确正确的返回格式正确的展示画面 后端逻辑分析代码总览 数据库表结构 需要实现的效果 前端需要的json格式&#xff1a;一定是一个完整…

【环境配置】Get more security updates through Ubuntu Pro with ‘esm-apps‘ enabled:

问题&#xff1a; Get more security updates through Ubuntu Pro with ‘esm-apps’ enabled Get more security updates through Ubuntu Pro with esm-apps enabled:vlc-plugin-qt libvlc5 vlc-data libvlccore9 vlc vlc-bin vlc-l10nlibopenexr-dev libopenexr25 libpostpro…

GAN:对抗生成网络,前向传播和后巷传播的区别

目录 GAN&#xff1a;对抗生成网络 损失函数 判别器开始波动很大&#xff0c;先调整判别器 生成样本和真实样本的统一&#xff1a;真假难辨​编辑 文字专图片​编辑 头像转表情包​编辑 头像转3D​编辑 后向传播 1. 前向传播&#xff08;forward&#xff09; 2. 反向传播&…

Spring Boot与Redisson的整合。分布式锁

Spring Boot与Redisson的整合可以帮助您在Spring Boot应用程序中使用分布式锁、缓存等功能。下面是一些基本步骤来整合Spring Boot与Redisson&#xff1a; 添加Maven/Gradle依赖&#xff1a; 在您的Spring Boot项目的pom.xml&#xff08;Maven&#xff09;或build.gradle&#…

Googel Earth Engine 配置Python 环境

1. 安装并配置python环境 此处不再赘述 2. 安装 earthengine-api pip install earthengine-api C:\Users\xixi>pip install earthengine-api Collecting earthengine-apiUsing cached earthengine_api-0.1.363-py3-none-any.whl Requirement already satisfied: google-c…

大模型技术实践(二)|关于Llama 2你需要知道的那些事儿

在上期文章中&#xff0c;我们简要回顾了Llama模型的概况&#xff0c;本期文章我们将详细探讨【关于Llama 2】&#xff0c;你需要知道的那些事儿。 01-Llama 2的性能有多好&#xff1f; 作为Meta新发布的SOTA开源大型语言模型&#xff0c;Llama 2是Llama模型的延续和升级。Ll…

Java“牵手”虾皮商品列表数据,关键词搜索虾皮(Shopee)商品数据接口,虾皮API申请指南

虾皮&#xff08;SHOPEE&#xff09;商城是一个网上批发购物平台&#xff0c;售卖各类商品&#xff0c;包括服装、鞋类、家居用品、美妆产品、电子产品等。要获取虾皮商品列表和商品详情页面数据&#xff0c;您可以通过开放平台的接口或者直接访问虾皮商城的网页来获取商品详情…

debian rules语法

当创建Debian软件包时&#xff0c;debian/rules 文件是非常重要的&#xff0c;它定义了软件包的构建规则。这个文件使用Makefile语法&#xff0c;指导构建、编译和安装软件包。下面将详细地介绍debian/rules文件的语法和常见用法。 基本结构&#xff1a; 一个简单的debian/rul…

QT中资源文件resourcefile的使用,使用API完成页面布局

QT中资源文件resourcefile的使用 之前添加图标的方法使用资源文件的方法创建资源文件资源文件添加前缀资源文件添加资源使用资源文件中的资源 使用API完成布局使用QHBoxLayout完成水平布局使用QVBoxLayout完成垂直布局使用QGridLayout完成网格布局 在Qt中引入资源文件好处在于他…

前端油猴脚本开发小技巧笔记

调试模式下&#xff0c;单击选中某dom代码&#xff0c;控制台里可以用$0访问到该dom对象。 $0.__vue___ 可以访问到该dom对应的vue对象。 jquery 对象 a,a[0]是对应的原生dom对象&#xff0c;$(原生对象) 得到对应的 jquery 对象。 jquery 选择器&#xff0c;加空格是匹配下…

git基础教程(24) git reflog查看引用日志

文章目录 1、`git reflog`命令说明2、`git reflog`命令显示内容3、具体的用法4、引起ref变化的操作有git reflog 命令是用来恢复本地错误操作很重要的一个命令,所以在这里对它进行一下整理。 1、git reflog命令说明 reflog翻译:Reference logs(参考日志) git reflog命令:…