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

news2024/9/22 12:35:59

一、基础
栈帧(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.coloradmin.cn/o/1527378.html

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

相关文章

小白向-使用git实现不同服务器改动的同步

背景 深度学习项目&#xff0c;已有可运行的backbone&#xff0c;已将此项目在github建库。 需要使用不同分支进行不同改动的测试&#xff1b;有两台服务器可供程序运行&#xff1b; 项目需求 以github云端仓库为媒介&#xff0c;实现不同服务器改动无痛关联。维护项目代码…

MS14_064 漏洞利用与安全加固

文章目录 环境说明1 MS14_064 简介2 MS14_064 复现过程3 MS14_064 安全加固 环境说明 渗透机操作系统&#xff1a;kali-linux-2024.1-installer-amd64漏洞复现操作系统: sc_winxp_pro_with_sp2 1 MS14_064 简介 要利用此漏洞则需要进行用户交互。通过发送电子邮件信息给本地登…

【云开发笔记No.4】DevOps的起源,定义和基本原则

DevOps&#xff0c;作为一组过程、方法与系统的统称&#xff0c;它的出现并不是偶然的&#xff0c;而是源于软件开发与运维领域长期以来所面临的挑战和痛点。其诞生背景可以追溯到敏捷开发模式的兴起以及持续开发所带来的运维问题。随着软件行业的飞速发展&#xff0c;传统的软…

Godot 学习笔记(3):IOC容器注入,以NlogServices为例

文章目录 前言环境注意事项Ioc注入文件夹设置Service服务搭建Nlog.configNlogService配置ButtonTest1Service控制反转Program主入口ButtonTest1从Ioc中获取服务 输出生命周期问题 总结 前言 Godot.Net中使用IOC之后&#xff0c;Godot的代码将会被极大的解耦。这里不不展开说明…

【大模型】直接在VS Code(Visual Studio Code)上安装CodeGeeX插件的过程

文章目录 一、什么是CodeGeeX&#xff08;一&#xff09;我理解的CodeGeeX&#xff08;二&#xff09;优缺点 二、CodeGeex下载、安装、注册&#xff08;一&#xff09;安装VS Code(Visual Studio Code)&#xff08;二&#xff09;下载安装CodeGeeX&#xff08;三&#xff09;注…

SpringBoot中使用验证码easy-captcha

easy-captcha使用的大概逻辑: 当一个请求发送到后端服务器请求验证,服务器使用easy-captcha生成一个验证码图片,并通过session将验证信息保存在服务器,当用户登录校验时候,会从ession中取出对比是否一致 但是前后端分离之后 由于跨域问题 以上就无法实现了 下面这种情况没…

Trait与生命周期

原文链接&#xff1a;(*∇&#xff40;*) 咦,又好了~ Rust – xiaocr_bloghttp://www.xiaocr.fun/index.php/2024/03/18/trait%E4%B8%8E%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/ 目录 Trait 定义trait 默认实现 trait作为参数 Trait Bound语法 通过指定多个 trait bound …

B003-springcloud alibaba 服务治理 nacos discovery ribbon feign

目录 服务治理服务治理介绍什么是服务治理相关方案 nacos实战入门搭建nacos环境安装nacos启动nacos访问nacos 将商品微服务注册进nacos将订单微服务注册进nacos订单服务通过nacos调用商品服务 实现服务调用的负载均衡什么是负载均衡代码实现负载均衡增加一个服务提供者自定义实…

【CKA模拟题】掌握Pod日志输出的秘密

题干 For this question, please set this context (In exam, diff cluster name) 对于这个问题&#xff0c;请设置这个上下文(在考试中&#xff0c;diff cluster name) kubectl config use-context kubernetes-adminkubernetes product pod is running. when you access log…

flask之ssti [WesternCTF2018]shrine1

打开题目 整理一下&#xff0c;代码: import flask import osapp flask.Flask(__name__) app.config[FLAG] os.environ.pop(FLAG) app.route(/)def index():return open(__file__).read()app.route(/shrine/)def shrine(shrine):def safe_jinja(s):s s.replace((, ).replac…

无人机三维建模过程中注意事项

无人机三维建模是指利用无人机技术进行三维建模&#xff0c;该方法通过无人机搭载的多种传感器&#xff0c;如摄像头、激光扫描仪等&#xff0c;获取建筑物的多角度影像数据&#xff0c;然后利用计算机视觉技术和三维重建算法&#xff0c;将这些影像数据转化为高精度的三维模型…

微服务技术栈SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式(五):分布式搜索 ES-下

文章目录 一、数据聚合1.1 聚合种类1.2 DSL实现聚合1.3 RestAPI实现聚合1.4 演示&#xff1a;多条件聚合 二、自动补全2.1 拼音分词器2.2 自定义分词器2.3 DSL自动补全查询2.5 实现酒店搜索框自动补全2.5.1 修改酒店索引库数据结构2.5.2 RestAPI实现自动补全查询2.5.3 实战 三、…

Docker部署Django项目——基础

1.服务器配置 1.1centos7 系统的安装 centos-7-isos-x86_64安装包下载) VMware安装自定义配置 选择对应的系统镜像 一般选择内核4核、内存8g、硬盘80g 相关配置 1.2.网络配置 1.2.1查看win电脑虚拟机VMnet8的ip 使用ipconfig查看虚拟机的ip 1.2.2配置虚拟机VMnet8的ip…

196基于matlab的计算器GUI可视化

基于matlab的计算器GUI可视化&#xff0c;具有加减乘除功能。可作为练习使用。程序已调通&#xff0c;可直接运行。 196 matlab GUI可视化 计算器 - 小红书 (xiaohongshu.com)

Flutter-数字切换动画

效果 需求 数字切换时新数字从上往下进入&#xff0c;上个数字从上往下出新数字进入时下落到位置并带有回弹效果上个数字及新输入切换时带有透明度和缩放动画 实现 主要采用AnimatedSwitcher实现需求&#xff0c;代码比较简单&#xff0c;直接撸 import dart:math;import p…

html-docx-js-typescript——将html生成docx文档

html-docx-js-typescript源码&#xff1a;GitHub - caiyexiang/html-docx-js-typescript: Convert HTML documents to docx format. html-docx-js地址&#xff1a;html-docx-js - npm *简单使用&#xff1a; 获取需要转为word文档的html节点&#xff0c;借助file-saver提供的…

MacBook远程桌面Windows使用Microsoft Remote Desktop for Mac_亲测使用

MacBook远程桌面Windows使用Microsoft Remote Desktop for Mac_亲测使用 像Windows上有自带的远程桌面连接软件.MacBook没有自带的远程连接Windows桌面的工具,需要安装软件来实现. 像远程桌面控制软件一般有 TeamViewer、向日葵远程控制, ToDesk, Microsoft Remote Desktop f…

Go语言gin框架中加载html/css/js等静态资源

Gin框架没有内置静态文件服务&#xff0c;但可以使用gin.Static或gin.StaticFS中间件来提供静态文件服务。 效果图如下&#xff1a; 一、gin 框架加载 Html 模板文件的方法 方式1&#xff1a;加载单个或多个html文件&#xff0c;需要指明具体文件名 r.LoadHTMLFiles("vie…

数字创新的引擎:探索Web3的前沿科技和商业模式

随着数字化时代的不断发展&#xff0c;Web3作为下一代互联网的重要组成部分&#xff0c;正逐渐成为数字创新的引擎。本文将深入探讨Web3的前沿科技和商业模式&#xff0c;揭示其在数字创新领域的重要作用和潜力。 1. 区块链技术的革命性 Web3的核心是区块链技术&#xff0c;它…

Flutter-自定义图片3D画廊

效果 需求 3D画廊效果 设计内容 StackGestureDetectorTransformPositioned数学三角函数 代码实现 具体代码大概300行 import dart:math;import package:flutter/material.dart; import package:flutter_xy/widgets/xy_app_bar.dart;import ../../r.dart;class ImageSwitc…