Java-JVM 虚拟机原理调优实战

一、基础
栈帧(Stack Frame)栈空间的 基本元素,用于 方法的调用和方法的执行的数据结构

堆内存用来存放由new创建的对象和数组。在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。

String是一个特殊的包装类数据。可以用: String str = new String(“abc”);String str = “abc”;两种的形式来创建,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。而第二种是先在栈中创建一个对String类的对象引用变量str,然后查找栈中有没有存放"abc",如果没有,则将"abc"存放进栈,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”。比较类里面的数值是否相等时,用equals()方法;

程序计数器:指向当前线程所指向的字节码指令的(地址)行号。

本地方法栈:存放方法名有native修饰,public static native void sleep(long millis) throws InterruptedException

栈帧和方法的关系:每一个方法的执行都对应了一个栈帧入栈到出栈的过程。

什么时候分配栈帧的内存?分配多少内存?
在编译代码的时候栈帧中需要多大的局部变量表,多深的操作数据栈都已经完全确定了,因此一个栈帧需要分配多少内存,不会受程序运行期数据的影响,只取决于虚拟机的实现。

二、图解
在这里插入图片描述
2.1 栈帧详解
2.1.1 局部变量表(Local variable Table): 主要关注的栈内存,就是JVM栈中的局部变量表的部分。
局部变量表(Local variable Table)是一组储值空间,用于存放方法参数和方法的内部定义的局部变量,并且在Java编译为.class文件的时候就分配了该方法所需要的局部变量表的最大容量.

2.1.2 变量槽(Variable Slot)

是局部变量表容量的最小单位 4字节 32 位长度(4* 8) ;
blloean ,byte ,char short,int float ,【refrence】,double 和 long 8字节型需要2个Slot空间.
【reference】引用地址:一般来说虚拟机都能从直接引用或者间接引用中查找对象一下2点
在堆区存放的数据的开始索引
数据类型在方法区的数据类型

2.1.3 实例
方法执行时候,虚拟机使用局部变量表完成参数的传递,如果执行的方法是实例对象的方法,局部变量的0索引(比如x00001)就是在堆区对象实例的引用(通过this可以访问到这个地址)
其他参数按照顺序排列。

2.1.4 Slot复用
为了节省空间,Slot是可以复用的,也就是PC计数器的指令指已经超出了某个变量的作用域,(执行完毕)那么这个变量对应的Slot就会给其他变量使用,
优点:节省栈帧空间
缺点:影响垃圾回收:如果有大方法占用比较多的Slot,然后又不及时清除,或者设置为null,垃圾回收器就不能回收该内存.

2.1.5 动态连接(Dynamic Link)每个帧都包含一个指向运行时常量池中该帧所属于方法的引用,持有这个引用是为了支付方法调用过程中的动态连接。
静态解析:在类的加载的阶段的解析2.3阶段会将符号(PI)转化为直接引用(0x001),这种转化也成为静态解析。
动态连接:另外一部分,在每次运行的时候将符号转化为直接引用,这部分称之为动态连接

2.1.6 方法返回地址(父帧)1.执行方法返回的2种方法:
1.正常退出:执行到return ,就退出方法2.异常退出:发生异常且未处理,
2.无论采用 哪一种方法,在退出后都需要返回之前方法调用的位置,就是父帧

一般来说,方法正常退出时候,PC计数器的值可以作为放回的地址,栈帧中会保存这个计数器中的值,但是方法异常退出时候,返回的地址通过异常处理器表来确定的,栈帧中一般不会保存这部分的信息。

2.1.7 操作数栈:
操作数栈 和 局部变量表一致
编译为class就确定大小
Slot为基础储存单位
作用:当一个方法开始时候,方法数栈始空的,执行中,各种字节码文件指令往操作数栈中读取内容和写入内容,入栈和出栈的操作
比如算术运算就是通过操作数栈来进行的,或者调用其他方法时候是用操作数栈来传递参数的

三、 栈溢出模拟 SO(StackOverflowError)
public class Demo {
public static void main(String[] args) {
new Demo().a();
}
private void a(){
b();
}
private void b(){
a();
}
}
调试运行栈帧截图:
在这里插入图片描述

方法每次调用都会新增一个栈帧,a() 方法和 b()循环调用导致栈内存暴满。
方法的递归调用同理

四、堆Heap
新生区:
新生区是类的诞生、成长、消亡的区域,
一个类在这里产生,应用,最后被垃圾回收器收集,结束生命。
新生区又分为两部分:伊甸区(Eden Space)和幸存者区(Survivor space),所有的类都是在伊甸区被new出来的。
幸村区有两个:0区(Survivor 0 space)和1区(Survivor 1space)。
当伊甸园的空间用完时,程序又需要创建对象,Jvm的垃圾回收器将对伊甸园区进行垃圾回收(Minor GC),将伊甸园区中的不再被其他对象所引用的对象进行销毁。然后将伊甸园区中的剩余对象移动到幸存0区。若幸存0区也满了,再对该区进行垃圾回收,然后移动到1区。
那如果1区也满了呢?再移动到养老区。若养老区也满了,那么这个时候将产生MajorGC(FullGC),进行养老区的内存清理。若养老区执行了Full GC之后发现依然无法进行对象的保存,就会产生OOM异常“OutOfMemoryError“。

如果出现java.lang.OutOfMemoryError:Java heap space异常,说明Java虚拟机的对内存不够。原因有二:  
(1)Java虚拟机的堆内存设置不够,可以通过参数-Xms、Xmx来调整。  
(2)代码中创建了大量大对象,并且长时间不能被垃圾收集器收集(存在被引用)

Java堆从GC的角度还可以细分为:新生代(Eden区、From Survivor区和To Survivor区)和老年代。
在这里插入图片描述

MinorGC的过程(复制->清空->互换),其中,Eden:From:To = 8:1:1
1:eden、SurvivorFrom复制到survivorTo,年龄+1  首先,把Eden和SurvivorFrom区域中存活的对象复制到SurvivorTo区域(如果有对象的年龄以及达到了老年的标准,则赋值到老年代区),同时把这些对象的年龄+1(如果SurvivorTo不够位置了就放到老年区) 
2:清空eden、SurvivorFrom  然后,清空Eden和SurvivorFrom中的对象  
3:SurvivorTo和SurvivorFrom互换  最后,SurvivorTo和SurvivorFrom互换,原SurvivorTo成为下一次GC时SurvivorFrom区

Java1.8之后将最初的永久代取消了,由元空间取代。  
在Java8中,永久代已经被移除了。被一个称为元空间的区域所取代。元空间的本质和永久代类似。  
元空间与永久代之间最大的区别在于:  
元空间并不在虚拟机中而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。类的元数据当如native memeory,字符串池和类的静态变量放入java堆中,这样可以加载多少类的元数据就不在由MaxPermSize控制,而由系统的实际可用空间来控制。
在这里插入图片描述

通过下面实例可以观察Heap 中新生区[eden->surviorFrom0->surviorFrom1]->老年代区[old] 内存变化到内存报错
报错:Exception in thread “main” java.lang.OutOfMemoryError: Java heap space

public class HeapOom {

private byte[] b = new byte[1024];public static void main(String[] args) throws InterruptedException {ArrayList<HeapOom> list = new ArrayList<>();while(true){list.add(new HeapOom());Thread.sleep(10);}
}

}
堆内存空间调整参数

参数名称 描述
-Xms 设置初始分配大小,默认为物理内存的1/64
-Xmx 最大分配内存,默认为物理内存的1/4
-XX:+PrintGCDetails 输出详细的GC处理日志
-XX:+PrintGCTimeStamps 输出GC的时间戳信息
-XX:+PrintGCDateStamps 输出GC的时间戳信息(以日期的形式,如2019-09-15T16:24:24.155+0800)
-XX:+PrintHeapAtGC 在GC进行处理的前后打印堆内存信息
-Xloggc:保存路径 设置日志信息保存文件

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

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

相关文章

多线程:线程安全、线程同步、线程通信

线程安全 什么是线程安全问题? 多个线程&#xff0c;同时操作同一个共享资源的时候&#xff0c;可能会出现业务安全问题。 1.线程安全问题出现的原因? 存在多个线程在同时执行同时访问一个共享资源存在修改该共享资源 用程序模拟线程安全问题 取钱案例 需求: 小明和小红…

2025张宇考研数学基础36讲,视频百度网盘+PDF

一、张宇老师全年高数体系&#xff08;听课用书指南&#xff09; 25张宇全程&#xff1a; docs.qq.com/doc/DTmtOa0Fzc0V3WElI 复制粘贴在浏览器上打开&#xff0c;就可以看到2025张宇的全部的啦&#xff01; 一般来说我们把考研数学划分为3-4个阶段&#xff0c;分别是基础阶…

2. IS-IS 基础实验

2.1 IS-IS 配置实验 2.1.1 实验介绍 2.1.1.1 学习目标 1. 实现 IS-IS 协议基本配置 2. 实现 IS-IS 协议 DIS 优先级修改 3. 实现 IS-IS 协议网络类型修改 4. 实现 IS-IS 协议外部路由引入 5. 实现 IS-IS 接口 cost 修改 6. 实现 IS-IS 路由渗透配置 2.1.1.2 实验组网介…

Git——标签详解

目录 Git标签1、概述1.1、标签是什么1.2、什么时候使用标签1.3、标签的分类 2、轻量标签&#xff08;lightweight tag&#xff09;3、有附注的标签&#xff08;annotated tag&#xff09;4、两种标签的区别5、删除标签 Git标签 1、概述 1.1、标签是什么 在Git中&#xff0c;…

Java基于springboot的篮球NBA球队管理系统ssm

本次将以NBA球队管理方面为切入点&#xff0c;论述了NBA球队管理的意义和内容&#xff0c;以此展开对NBA球队管理系统的开发与建设的详细分析。从数据挖掘的角度出发&#xff0c;了解信息管理系统的作用&#xff0c;对NBA球队管理系统的过程以及用处进行更深一步的研究&#xf…

Java 世界破破烂烂,电音小猫缝缝补补

Java 世界破破烂烂&#xff0c;电音小猫缝缝补补 Java 通用代码生成器光 2.4.0 电音之王尝鲜版六正在研发&#xff0c;昨天发布了介绍视频&#xff0c;请见&#xff1a; https://www.bilibili.com/video/BV1yD421j7UP/ 电音之王尝鲜版六支持哑数据模式&#xff0c;支持枚举。…

win10笔记本在显示设置中不慎将主显示器禁用掉导致开机黑屏的解决方案

因为笔记本电脑的显示扩展接口有问题&#xff0c;所以在电脑开机之后&#xff0c;会误识别出几个不存在的扩展屏幕&#xff0c;所以我就想从显示设置中将这几个误识别出来的扩展屏幕禁用掉&#xff08;不然鼠标总是移动到主屏幕边界之外的地方&#xff09;&#xff0c;在显示设…

RabbitMQ介绍及搭建

架构 RabbitMQ是实现了高级消息队列协议&#xff08;AMQP&#xff09;的开源消息代理软件&#xff0c;使用erlang语言编写&#xff0c;依赖Erlang环境运行。 Broker&#xff1a;运行消息队列服务进程的节点&#xff0c;包含Exchange、Queue&#xff1b; Producer&#xff1a;消…

蓝桥杯刷题总结(Python组)

1、蛇形矩阵 解题思路&#xff1a;每次赋值后都对方向进行改变&#xff0c;一般上下左右就是&#xff08;-1&#xff0c;0&#xff09;&#xff0c;&#xff08;0&#xff0c;1&#xff09;&#xff0c;&#xff08;1&#xff0c;0&#xff09;&#xff0c;&#xff08;0&…

TSINGSEE青犀AI智能分析网关V4酿酒厂安全挂网AI检测算法

在酿酒行业中&#xff0c;安全生产一直是企业经营中至关重要的一环。为了确保酒厂生产过程中的安全&#xff0c;TSINGSEE青犀AI智能分析网关V4的安全挂网AI检测算法发挥了重要作用。 TSINGSEE青犀AI智能分析网关V4的安全挂网检测算法是针对酒厂里酒窖挂网行为进行智能检测与识…

爬虫 Day2

resp.close()#关掉resp 一requests入门 &#xff08;一&#xff09; 用到的网页&#xff1a;豆瓣电影分类排行榜 - 喜剧片 import requestsurl "https://movie.douban.com/j/chart/top_list" #参数太长&#xff0c;重新封装参数 param {"type": "…

【Qt问题】使用QSlider创建滑块小部件无法显示

问题描述&#xff1a; 使用QSlider创建滑块小部件用于音量按钮的时候&#xff0c;无法显示&#xff0c;很奇怪&#xff0c;怎么都不显示 一直是这个效果&#xff0c;运行都没问题&#xff0c;但是就是不出现。 一直解决不了&#xff0c;最后我在无意中&#xff0c;在主程序中…

LLM 面试知识点——模型基础知识

1、主流架构 目前LLM(Large Language Model)主流结构包括三种范式,分别为Encoder-Decoder、Causal Decoder、Prefix Decode。对应的网络整体结构和Attention掩码如下图。 、 各自特点、优缺点如下: 1)Encoder-Decoder 结构特点:输入双向注意力,输出单向注意力。 代表…

MySQL中数据库表的监控

MySQL中数据库表的监控 &#xff08;1&#xff09;查看数据库中当前打开了哪些表&#xff1a;show OPEN TABLES &#xff0c;如图6-1-5所示。另外&#xff0c;还可以通过show OPEN TABLES where In_use > 0过滤出当前已经被锁定的表。 查看数据库中表的状态&#xff1a;SHO…

css3 实现html样式蛇形布局

文章目录 1. 实现效果2. 实现代码 1. 实现效果 2. 实现代码 <template><div class"body"><div class"title">CSS3实现蛇形布局</div><div class"list"><div class"item" v-for"(item, index) …

聚类分析 | Matlab实现基于NNMF+DBO+K-Medoids的数据聚类可视化

聚类分析 | Matlab实现基于NNMFDBOK-Medoids的数据聚类可视化 目录 聚类分析 | Matlab实现基于NNMFDBOK-Medoids的数据聚类可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 NNMFDBOK-Medoids聚类&#xff0c;蜣螂优化算法DBO优化K-Medoids 非负矩阵分解&#xff08…

【机器学习-01】机器学习基本概念与建模流程

机器学习的过程本质上是一个不断通过数据训练来提升模型在对应评估指标上表现的过程。在此过程中&#xff0c;为模型提供有效的反馈并基于这些反馈进行持续的调整是至关重要的。只有当这个过程顺利进行时&#xff0c;模型才能得到有效的训练&#xff0c;机器才能真正实现学习。…

鸿蒙4.0ArkUI快速入门(一)应用模型

ArkUI篇 应用模型Stage模型FA模型模型对比 应用模型 应用模型是HarmonyOS为开发者提供的应用程序所需能力的抽象提炼&#xff0c;它提供了应用程序必备的组件和运行机制。 HarmonyOS先后提供了两种应用模型&#xff1a; FA&#xff08;Feature Ability&#xff09;模型&…

Machine Learning ---- Gradient Descent

目录 一、The concept of gradient&#xff1a; ① In a univariate function&#xff1a; ②In multivariate functions&#xff1a; 二、Introduction of gradient descent cases&#xff1a; 三、Gradient descent formula and its simple understanding: 四、Formula o…

MATLAB教程

目录 前言一、MATLAB基本操作1.1 界面简介1.2 搜索路径1.3 交互式命令操作1.4 帮助系统 二、MATLAB语言基础2.1 数据类型2.2 MATLAB运算2.2.1 算数运算2.2.2 关系运算2.2.3 逻辑运算 2.3 常用内部函数2.4 结构数据与单元数据 三、MATLAB程序设计3.1 M文件3.2 函数文件3.3 程序控…