JVM——引言+JVM内存结构
引言
什么是JVM
定义:
Java VirtualMachine -java 程序的运行环境 (ava 二进制字节码的运行环境)
好处:
- 一次编写,到处运行
- 自动内存管理,垃圾回收功能
- 数组下标越界检查,
- 多态
比较:
jvm jre jdk
学习jvm的作用
- 面试
- 理解底层实现原理
- 中高级程序员的必备技能
常见的jvm
自己百度查找
jvm的组成
内存结构
程序计数器
定义
Program Counter Register 程序计数器(寄存器)
作用
如下图所示
右边就是简单的java代码打印操作,编译成左侧的二进制字节码。
经过解释器——>机器码——>CPU执行。
程序计数器在这里面的作用就是记住下一条jvm指令的执行地址。
第一条指令地址是0,第一条指令交给解释器去执行的同时会把第二条指令的地址3放入程序计数器。第一条执行完之后,解释器会去取出3来执行......
物理实现: 通过CPU中寄存器(速度快)实现
特点:
线程私有
每个线程都有自己的程序计数器。
每一个线程会有被分配一个时间片,在当前时间片内不能执行完会去执行别的线程的代码,直到轮到下一个时间片。
切换到别的线程时要记住当前执行到哪里,还是要用到程序计数器。通过私有的程序计数器知道下一行代码的地址。
唯一不会存在内存溢出的区
虚拟机栈
栈是一种普通的先进后出的数据结构。
java的虚拟机栈则是线程运行需要的内存空间。
一段代码有多个方法组成,一个栈帧表示一次方法的调用,栈帧就是每个方法运行需要的内存。
运行:调用第一个方法时会给第一个方法划分一个栈帧空间,并压入栈内,执行完后会出栈,也会释放该方法占用的内存。
然后方法1调用方法2时会产生一个方法2的栈帧并入栈,然后方法2调用方法3也会产生并入栈,如下图所示。
定义
Java Virtual Machine Stacks (Java 虚拟机栈)
- 每个线程运行时所需要的内存,称为虚拟机栈
- 每个栈由多个栈帧 (Frame) 组成,对应着每次方法调用时所占用的内存
- 每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法
栈帧大小由方法里的参数以及局部变量的个数决定
问题辨析
1.垃圾回收是否涉及栈内存?
栈内存是一次次方法调用产生的栈帧内存,调用结束后会弹出栈,会自动回收,不需要垃圾回收 管理,垃圾回收是回收堆内存中的无用对象。
2.栈内存分配越大越好吗?
运行java代码时是可以指定栈内存大小的,使用-Xss size,下图还有不同系统下默认栈内存的大小和设定内存的示例。
栈内存越大会让线程数变少,512mb的物理内存下,每个线程的栈内存设置1mb大小可以运行512个,设置2mb大小可以运行256个线程。不会提高线程效率,但可以增加递归的层数。
3.方法内的局部变量是否线程安全?
根据该变量是每个线程共享还是线程私有判断。下图是一个方法,方法内有一个局部变量。
该方法被调用两次时会有两个不同的栈。每个线程都会有私有的局部变量。因此这里不会有线程干扰的问题。
假如将x改为static int x=0;的话就会出现线程干扰,如果不加保护的话会有线程安全问题。
总结:共享需要考虑线程安全,私有就不需要考虑。
- 如果方法内的局部变量没有逃离方法的作用范围,则是线程安全。
- 如果是局部变量引用了对象,并逃离方法的作用方法,需要考虑线程安全(引用传递和值传递的问题)
栈内存溢出
- 栈帧过多导致栈内存溢出(栈帧过多爆栈) : 通常在的递归导致。
- 单片栈帧过大导致栈内存溢出(太大了,已经塞满了)
一般不会有单片过大,栈帧里都是方法参数和局部变量。可以通过设置栈内存大小达到
在将对象转换成json对象时也会有栈溢出,这种两个类的循环问题会导致json解释器出现问题。
可以通过一个@JsonIgnore注解达到在json转换对象时忽略变量的效果。
线程运行诊断
案例1: cpu 占用过多
linux环境下运行一段java代码导致cpu占用过高,可以使用top命令定位到哪一个进程占用,但看不见是哪一个线程导致的。
在linux下使用ps H -eo pid,tid,%cpu 命令可以看见所有线程的pid(进程号),tid(线程号),%cpu(cpu占用)。
使用ps H -eo pid,tid,%cpu | grep 32655 后面加上| grep pid过滤无关进程的线程。
- 用top定位哪个进程对cpu的占用过高
- ps H -eo pid,tid,%cpu | grep pid (用ps命令进一步定位是哪个线程引起的cpu占用过高)
- jstack 进程id (可以根据线程id 找到有问题的线程,进一步定位到问题代码的源码行号)
生产环境不推荐jstack,因为打印线程信息jvm会暂停其他线程
然后将线程编号32665转换成16进制(7F99)在输出内容中查找
在jstack 输出内容中可以看见一个nid=Ox7f99的线程,状态为RUNNABLE.
看见问题出在第8行代码。如下图源码第8行是个死循环。
nid、pid 和 tid 是计算机系统中常用的三个标识
- nid (Node ID) 是指在分布式系统中,每个节点的唯一标识
- pid (Process ID) 是指操作系统中每个进程的唯一标识。
- tid (Thread ID) 是指操作系统中每个线程的唯一标识。
案例2: 程序运行很长时间没有结果
线程死锁导致的无结果下使用jstack命令查看,下输出内容最后可以看见有关死锁信息。
两个线程都想获得a,b,但是都在等对方放开拥有的对象,然后陷入死锁。
产生死锁的四个必要条件:互斥、不可剥夺、请求和保持、循环等待。
本地方法栈
定义: java虚拟机在调用本地方法时需要给本地方法提供的内存空间
在Object这个类中就有很多,比如Object的clone方法的声明是native,这个native的实现是c/c++,java代码是间接调用native
堆
定义
通过 new 关键字,创建对象都会使用堆内存
特点:
- 它是线程共享的,堆中对象都需要考虑线程安全的问题
- 有垃圾回收机制 (不再被引用的对象会被回收)
堆内存溢出
下图所示方法中String类型的对象a会一次次变大,直至堆溢出。
运行结果: 溢出内存错误: java 堆 空间
使用-Xmx size改变堆空间大小。
修改前26次才溢出,修改后17次溢出。
有可能堆内存较大,运行时间短,在系统前期看不出问题,后期才会爆掉,故测试时可以将堆内存设置较小进行排查。
堆内存诊断
相关工具:
1.jps 工具
查看当前系统中有哪些 java 进程
2. jmap 工具
查看堆内存占用情况 jmap -heap 进程id (只能看某一瞬间的情况)
3.jconsole 工具
图形界面的,多功能的监测工具,可以连续监测
4.jvisualVM 工具
图形化界面,可以抓取当前快照
案例1
new一个10MB的数组对象,后面置为null,然后gc显式回收。
运行后通过jps查看进程id,jmap -heap 18756在1~2,2~3,3之后三个时间点抓取快照信息。
最大堆内存占用MaxHeapSize是4个G
Eden Space就是专门为new 出来的对象准备的。
1~2之间
数组创建之前使用了6Mb
2~3之间
创建数组对象之后使用16mb,
3之后
垃圾回收之后变成1.2mb
使用jconsole工具的界面。
案例2
垃圾回收之后,内存占用任然很高。
新生代被回收了,老年代没有被回收。
新生代剩8mb
老年代剩200mb
使用新的工具jvisualvm可视化虚拟机
保存快照之后进行查找最大的类
查看最大的ArrayList实例的具体信息
源代码
两百个Student对象,每个都开了一个1mb大小的byte数组。并且一直在作用范围内,无法回收,内存占用居高不下。
通过可视化界面的堆 dump按钮进行排查。
方法区
定义
按照jdk_jvm_1.8中的定义
- 方法区是所有java虚拟区线程共享的区域。
- 存储了和类的结构相关的信息。
- 有成员变量filed,method data方法数据,成员方法、构造器方法的代码以及运行时常量值run-time constant pool等等
- 在虚拟机启动时被创建
- 逻辑上是堆的组成部分(1.8以前用的堆内存,1.8以后用的是系统内存)
- 方法区也会导致内存溢出
组成
永久代和元空间都是方法区这个概念的实现。
永久代和元空间最本质的区别就是 前者使用的是jvm内存 后者使用的是操作系统内存。
图中常量池是运行时常量池。
方法区内存溢出
- 1.8 以前会导致永久代内存溢出
- 1.8 之后会导致元空间内存溢出
下图代码就是一个加载了10000个类的代码,最外层继承实现了类加载器,在循环内指定版本号,类名,包名,父类,接口等信息创建一个新类。
这里元空间和永久代都没有设置上限,这里需要设置元空间和永久代大小。
-XX:MaxMetaspaceSize=8m 元空间
-XX:MaxPermSize=8m 永久代
元空间运行报异常
永久代报异常
场景:
- spring
- mybatis
spring和mybatis都使用到了cglib技术。
运行时常量池
下面的这段代码的二进制字节码含有如下信息。
使用如下命令查看该代码反编译后的结果
javap -v HelloWorld.class
常量池部分
虚拟机指令部分
执行指令时下面第一条就是获取静态变量,#2在常量池里面找。
ldc是找到一个引用地址。
定义:
- 常量池,就是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息
- 运行时常量池,常量池是*.class 文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址
运行时常量池里面#1,#2...这些会变成内存地址。
相关文章:

JVM——引言+JVM内存结构
引言 什么是JVM 定义: Java VirtualMachine -java 程序的运行环境 (ava 二进制字节码的运行环境) 好处: 一次编写,到处运行自动内存管理,垃圾回收功能数组下标越界检查,多态 比较: jvm jre jdk 学习jvm的作用 面试理解底层实现原理中…...
open cv学习 (十)图形检测
图形检测 demo1 # 绘制几何图像的轮廓 import cv2img cv2.imread("./shape1.png")gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 将图像二值化 t, binary cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 检测图像中的所有轮廓 contours, hierarchy cv2.f…...

【C语言】字符函数和字符串函数
目录 1.求字符串长度strlen 2.长度不受限制的字符串函数 字符串拷贝strcpy 字符串追加strcat 字符串比较strcmp 3.长度受限制的字符串函数介绍strncpy strncat 编辑strncmp 4.字符串查找strstr 5.字符串分割strtok 6.错误信息报告 strerror perror 7.字符分类函…...

前馈神经网络正则化例子
直接看代码: import torch import numpy as np import random from IPython import display from matplotlib import pyplot as plt import torchvision import torchvision.transforms as transforms mnist_train torchvision.datasets.MNIST(root…...

spring的核心技术---bean的生命周期加案例分析详细易懂
目录 一.spring管理JavaBean的初始化过程(生命周期) Spring Bean的生命周期: 二.spring的JavaBean管理中单例模式及原型(多例)模式 2.1 . 默认为单例,但是可以配置多例 2.2.举例论证 2.2.1 默认单例 2.2…...

【Maven教程】(一)入门介绍篇:Maven基础概念与其他构建工具:理解构建过程与Maven的多重作用,以及与敏捷开发的关系 ~
Maven入门介绍篇 1️⃣ 基础概念1.1 构建1.2 maven对构建的支持1.3 Maven的其他作用 2️⃣ 其他构建工具2.1 IDE2.2 Make2.3 Ant2.4 Jenkins 3️⃣ Maven与敏捷开发🌾 总结 1️⃣ 基础概念 "Maven"可以翻译为 “知识的积累者” 或 “专家”。这个词源于波…...

今天,谷歌Chrome浏览器部署抗量子密码
谷歌已开始部署混合密钥封装机制(KEM),以保护在建立安全的 TLS 网络连接时共享对称加密机密。 8月10日,Chrome 浏览器安全技术项目经理Devon O’Brien解释说,从 8 月 15 日发布的 Chrome 浏览器 116 开始,谷…...

SUMO traci接口控制电动车前往充电站充电
首先需要创建带有停车位的充电站(停车场和充电站二合一),具体参考我的专栏中其他文章。如果在仿真的某个时刻,希望能够控制电动车前往指定的充电站充电,并且在完成充电后继续前往车辆原来的目的地,那么可以使用以下API:…...
现代CSS中的换行布局技术
在现代网页设计中,为了适应不同屏幕尺寸和设备类型,换行布局是一项重要的技术。通过合适的布局技术,我们可以实现内容的自适应和优雅的排版。本文将介绍CSS中几种常见的换行布局技术,探索它们的属性、代码示例和解析,帮…...
简单理解Python中的深拷贝与浅拷贝
I. 简介 深拷贝会递归的创建一个完全独立的对象副本,包括所有嵌套的对象,而浅拷贝只复制嵌套对象的引用,不复制嵌套对象本身。 简单来说就是两者都对原对象进行了复制,因此使用is运算符来比较新旧对象时,返回的都是F…...

C++之std::pair<uint64_t, size_t>应用实例(一百七十七)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…...

前端打开后端返回的HTML格式的数据
前端打开后端返回的 HTML格式 的数据: 后端返回的数据格式如下示例: 前端通过 js 方式处理(核心代码如下) console.log(回调, path); // path 是后端返回的 HTML 格式数据// 必须要存进localstorage,否则会报错&am…...
How to deal with document-oriented data
Schema designData models for e-commerceNuts and bolts of databases, collection, and documents. Principles of schema design What are your application access pattern?Whats the basic unit of data? the basic unit of data is the BSON documentWhat are the ca…...
Http 状态码汇总
文章目录 Http 状态码汇总1xx(信息性状态码)2xx(成功状态码)3xx(重定向状态码)4xx(客户端错误状态码)5xx(服务器错误状态码) Http 状态码汇总 1xx(…...
mysql自定义实体类框架
根据表结构自动生产实体类和方法,根据反射与io生成,可自定义扩展方法 package com.digital.web.front; /*** pom依赖* <dependency>* <groupId>mysql</groupId>* <artifactId>mysql-connector-java</artifactId>* <version>5.1.27</ve…...
批量将Excel中的第二列内容从拼音转换为汉字
要批量将Excel中的第二列内容从拼音转换为汉字,您可以使用Python的openpyxl库来实现。下面是一个示例代码,演示如何读取Excel文件并将第二列内容进行拼音转汉字: from openpyxl import load_workbook from xpinyin import Pinyin # 打开Exce…...
消息推送:精准推送,提升运营效果,增添平台活力
对于app开发者而言,没有什么途径比消息推送更能直接、即时地触及目标用户群体了。消息推送与我们的日常生活息息相关,各种APP的状态和通知都通过消息推送来告知用户,引起用户的注意,吸引用户点开app。总而言之,推送服务…...

[保研/考研机试] KY43 全排列 北京大学复试上机题 C++实现
题目链接: 全排列https://www.nowcoder.com/share/jump/437195121692001512368 描述 给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。 我们假设对于小写字母有a < b < ... < y < z,而且给定的字符串中的字…...
Java将时间戳转化为特定时区的日期字符串
先上代码: ZonedDateTime dateTime ZonedDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()),zone ); //2019-12-01T19:01:4608:00String formattedDate dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd") ); //2019-12-…...

【算法挨揍日记】day03——双指针算法_有效三角形的个数、和为s的两个数字
611. 有效三角形的个数 611. 有效三角形的个数https://leetcode.cn/problems/valid-triangle-number/ 题目描述: 给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数。 解题思路: 本题是一个关于三角形是否能成立…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...