当前位置: 首页 > article >正文

【JVM】- 内存结构

引言

JVM:Java Virtual Machine

  • 定义:Java虚拟机,Java二进制字节码的运行环境
  • 好处
    • 一次编写,到处运行
    • 自动内存管理,垃圾回收的功能
    • 数组下标越界检查(会抛异常,不会覆盖到其他代码)
    • 多态
  • 比较
    在这里插入图片描述

内存结构

程序计数器(Program Counter Register)

作用:记住下一条JVM的机制
特点
- 线程私有的
- 不会存在内存溢出

虚拟机栈

定义

  • 每个线程运行所需要的内存;
  • 每个栈由多个栈帧组成,对应每次方法调用所占的内存;
  • 每个线程只有一个活动栈帧,对应每次方法调用所占用的内存

垃圾回收只设计堆内存中的无用对象,不涉及栈内存。
栈内存的分配可以通过-Xss来设置,并不是越大越好。
方法内的局部变量不一定是线程安全的:

  • 如果这个局部变量没有逃离方法的作用范围,则他是线程安全的
  • 如果局部变量引用了对象,并逃离了方法的作用范围,则需要考虑线程安全

栈内存溢出

  • 栈帧过多导致栈内存溢出:递归调用
  • 栈帧过大导致栈内存溢出

本地方法栈

本地方法使用的内存就是本地方法栈(由C、C++代码写的方法)

通过new关键字创建的对象都会使用堆内存

特点

  • 是线程共享的,堆中的对象都要考虑线程安全问题
  • 有垃圾回收机制

前面的程序计数器虚拟机栈本地方法栈都是每个线程独有的,但是堆是线程共享的
可以使用-Xmx参数来设置堆内存大小
可以使用jconsole工具来查看堆内存占用情况

方法区

在这里插入图片描述

  • 共享性:方法区是线程共享的内存区域
  • 逻辑部分:方法区是JVM规范中的逻辑概念,具体实现因JVM版本而异
  • 存储:和类相关的信息(成员方法、构造器、成员变量)、运行时常量池、静态变量、方法字节码、字段和方法信息

内存溢出

  • 1.8以前导致永久代内存溢出(1.8以前,方法区由永久代实现,位于堆中)PermGen space
  • 1.8之后导致元空间内存溢出(1.8以后,方法区由元空间实现,使用本地内存)Metaspace

常量池:一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息
运行时常量池:常量池是.class文件中的,当类被加载时,他的常量池信息就会被放入运行时常量池,并把里面的符号地址变为真实地址。

StringTable

常量池中的信息,都会被加载到运行时常量池中。

  • 常量池中的字符串只是符号,第一次用到时才会变成对象(懒加载)
  • 利用运行时常量池的机制,来避免重复创建字符串对象
  • 字符串变量拼接的原理是StringBuilder(1.8、在中)
  • 字符串常量拼接的原理是编译器优化(在编译期如果确定字符串,就把它放入常量池中)
  • 可以使用intern方法,主动将常量池中还没有的字符串对象放入串池中
    • 1.8:将这个字符串对象尝试放入串池,如果有则不会放入;如果没有则放入串池,会把串池中的对象返回
    • 1.6:会把这个字符串对象尝试放入串池,如果有则不会放入;如果没有会把此对象复制一份,放入串池,会把串池中的对象返回(调用intern()方法创建的对象和放入串池的对象是两个对象)
public class Main {public static void main(String[] args) {/*StringTable ["a", "b", "ab"](hashtable结构,不能扩容)s1、s2、s3:在常量池中s4:new String("ab")*/String s1 = "a", s2 = "b", s3 = "ab"; // 懒加载:用到了才会把对应的字符串对象放入常量池中String s4 = s1 + s2; // 在堆中System.out.println(s3 == s4); // false/*s5:在编译期间已经确定结果为"ab",所以直接从常量池中取即可*/String s5 = "a" + "b"; // 在常量池中System.out.println(s3 == s5); // true/*x1.intern():将字符串对象尝试放入串池中,如果有则不会放入;如果没有,则放入串池,并返回串池对象*/String x1 = new String("c") + new String("d"); // 变量动态拼接,此时x1在堆中;"c"、"d"会在串池中String x2 = x1.intern();System.out.println("cd" == x1); // trueSystem.out.println("cd" == x2); // true/*String str1 = "cd";【串池】:["cd"]本来str2是在堆中,"c", "d"放入串池:String str2 = new String("c") + new String("d");【串池】:["cd", "c", "d"]使用str2.intern()方法,会将str2尝试放入串池【串池】:["cd", "c", "d"]将"cd"放入串池时,发现串池中已经存在该对象,"cd"对象放入失败*/String str1 = "cd";String str2 = new String("c") + new String("d");str2.intern();System.out.println(str1 == str2); // false}
}

StringTable位置

在这里插入图片描述

  • JDK1.6:
    • 运行时常量池位于永久代中(方法区)
    • 字符串常量池位于永久代中(方法区)
  • JDK1.8:
    • 运行时常量池位于元空间中(方法区)
    • 字符串常量池位于堆中(不在方法区里了)

由于永久代的Full GC触发时机是:永久代的空间不足才会触发,就会导致StringTable的回收时机并不会很频繁,但是StringTable又是一个需要被频繁使用的,这样很容易就会导致永久代空间不足。所以JDK8才把String Table存放位置改堆中。

StringTable性能调优

本质:调整HashTable中的桶个数
通过-XX:StringTableSize=200000调整HashTable中的桶个数

如果系统中字符串常量的个数较多,可以适当的调整HashTable中的桶大小,减小hash冲突。

案例】:某平台要存储用户大量的信息,需要存储大量的用户信息,但是用户的地址信息大部分都可能是重复的,如果不加以区分,直接把这么多重复的地址信息全部存入内存,那么会占用大量的堆内存。它的解决方法就是采用字符串的intern()方法,这样就可以去除重复的地址,相同的地址只会在串池中存储一份,这样也能减少字符串对于内存的占用。

结论】:如果应用里有大量的重复的字符串,可以考虑使用字符串的intern()方法,将这些字符串全部放入常量池中,这样可以避免这些字符串重复存储。

直接内存(操作系统的内存,不属于java虚拟机)

  • 常见于NIO操作,用于数据缓冲区
  • 回收分配成本高,读写性能高
    在这里插入图片描述

java程序每次从磁盘文件中读取,都需要先读取到系统内存,再读取到java堆内存,这样会造成很多不必要的浪费。

改进】:划出一块内存区域(direct memory),在这块内存区域中,java代码和系统内存都可以直接访问。从磁盘文件中读取后把数据放入直接内存,java代码也可以访问到这个直接内存,这样就会少了一次缓冲区的赋值操作。
在这里插入图片描述

  • 不受JVM内存回收管理,垃圾回收并不会导致直接内存释放,因为直接内存是操作系统的内存,不属于java虚拟机。
    • 使用Unsafe对象完成直接内存的分配回收,并且回收需要主动调用freeMemory方法
    • ByteBuffer的实现类内部,使用了Cleaner(虚引用)来检测ByteBuffer对象,一旦ByteBuffer对象被垃圾回收,那么就会有ReferenceHandler线程通过Cleaner的clean方法调用freeMemory来释放直接内存。

相关文章:

【JVM】- 内存结构

引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...