JVM 常量池、即时编译与解析器、逃逸分析

一、常量池 

1.1、常量池使用 的数据结构

常量池底层使用HashTable

key 是字符串和长度生成的hashValue,然后再hash生成index, 改index就是key;Value是一个HashTableEntry;
1、key
    hashValue = hash string(name, len)
    index = hash to index(hashValue);
    1、根据字符串(即 name)以及字符串的长度计算出hashValue
    2、根据hashValue计算出index,这个index就是key 
2、value
    1、HashtableEntry<oop, mtSymbol>* entry = new entry(hashValue, string());
    2、将Java的string类的实例instanceOopDesc封装成HashtableEntry
    3、struct HashtableEntry {
        INT PTR hash;
        void* key;
          void* value;  instanceopDesc
        HashtableEntry* next;
      };

1.2、JVM底层是如何操作常量池

String s = "1";

1、去字符串常量池中去查, 有直接返回对应的string对象
2、如果没有,就会创建string对象、char数组对象,
3、将这个string对象对应的InstanceOopDesc封装成HashtableEntry,作为StringTable的value进行存储

4、new String()就是在堆上又创建一个对象char[] 指向typeArrayOopDesc

二、即使编译与解析器

2.0 编译过程

  1. .java源文件通过编译器(javac.exe)编译成.class文件
  2. JVM通过ClassLoader对.calss文件进行解释(自解码解释器和JIT即使编译器)—该过程需要调用核心类1

3、说说JVM内的解释器(Just In Time Compiler)和即时编译器(JIT)

作用:解释器和即时编译器(Just In Time Compiler,JIT)是JVM中将字节码转化为机器码的工具。


解释器: 解释器将字节码解析成集器能识别的机器码。解释方式是一行一行的读取,解释到哪就执行到哪。
即使编译器:以方法为单位,将热点代码的字节码一次性转为机器码,并在本地缓存起来的工具。避免了部分代码被解释器逐行解释执行的效率问题。

2.1 编译器

2.1.1 即时编译器种类

    C1
    C2

2.1.2 即时编译器 分层编译

    分层编译
        c1编译器是client模式下的即时编译器
            1、触发的条件相对C2比较宽松:需要收集的数据较少
            2、编译的优化比较浅:基本运算在编译的时候运算掉了 final
            3、c1编译器编译生成的代码执行效率较C2低
        c2编译器是server模式下的即时编译器
            1、触发的条件比较严格,一般来说,程序运行了一段时间以后才会触发
            2、优化比较深
            3、编译生成的代码执行效率较C1更高
        混合编译
            程序运行初期触发C1编译器
            程序运行一段时间后触发C2编译器

2.1.3 编译器与解释器关系

        即时编译器生成的代码就是给模板解释器用的

  • 解释器:程序执行的时候,解释器首先发挥作用,省去了编译器编译时间,加快程序的执行效率
  • 编译器:在程序运行过程中,随着时间的推移,编译器就开始慢慢发挥了作用,把热点代码编译成本地代码后,以后执行相同的代码,即可直接获取,更高的执行效率。
  • 解释器和编译器相互配合,使程序高效执行。

2.1.4 问题分享

分享阿里早年的一个故障
    热机切冷机故障: 冷机启动后有大量代码编译,造成cpu爆炸,机器宕机
        冷机:刚启动的时候
        热机:启动很长时间

2.1.5 热点代码存放位置

热点代码缓存区在 方法区,C++代码中以 CodeCache存在
调优中的一种
server编译器模式下代码缓存大小则起始于 2496KB

client编译器模式下代码缓存大小起始于 160KB

2.1.6 触发条件

热点代码被编译为 硬编码即汇编指令
热点代码
即时编译的最小单位不是一个函数,而是代码块 (for、while)

判断热点代码探测方法

采样式的热点探测

周期性检查线程栈顶,经常出现在栈顶的就是热点代码

  • 优点:简单高效。

  • 缺点:容易受到线程阻塞或其他因素影响

方法调用计数器

client 编译器模式下,N 默认的值 1500
Server 编译器模式下,N 默认的值则是 10000

可通过 -XX:CompileThreadhold设置,在一段时间内被调用次数。当超过一定的时间限度,如果方法的调用次数仍然不足以让它提交给即时编译器编译,那么这个方法的调用计数器就会被减少一半,这个过程称为方法调用计数器热度的衰减(Counter Decay),而这段时间就成为此方法的统计的半衰周期( Counter Half Life Time)。进行热度衰减的动作是在虚拟机进行垃圾收集时顺便进行的,可以使用虚拟机参数 -XX:CounterHalfLifeTime 参数设置半衰周期的时间,单位是秒。
 

回边计数器(Back Edge Counter )

        统计一个方法中循环体代码执行的次数,在字节码中遇到控制流向后跳转的指令称为“回边”( Back Edge )。显然,建立回边计数器统计的目的就是为了触发 OSR 编译。关于这个计数器的阈值, HotSpot 提供了 -XX:BackEdgeThreshold 供用户设置,但是当前的虚拟机实际上使用了 -XX:OnStackReplacePercentage 来简介调整阈值。

2.2 解析器

2.2.1 解释器种类

字节码解释器
Java字节码->c++代码->硬编码

模板解释器

Java字节码->硬编码

2.2.2 运行模式

解析器有三种运行模式
1、-Xint 纯字节码解释器
2、-Xcomp 纯模板解释器
    程序比较大
3、-Xmixed 字节码解释器 + 模板解释器

比较一下这三种运行模式的性能
231
321
与程序大小有关,程序较大时Xcomp会使程序变得更大,编译器很慢

三、逃逸分析

3.1 逃逸

什么对象不会逃逸

局部对象不会产生逃逸

什么对象会逃逸

共享变量,方法返回值,参数 会产生逃逸

3.2 分析 

三种手段

3.2.1 标量替换

public void test2() {System.out.println(EA);System.out.println(1);
}

3.2.2 锁消除

局部对象new Object(),锁被消除掉

public void test() {synchronized (new Object()){System.out.println("=============");}
}
public void test() {System.out.println("=============");
}

3.2.3 栈上对象分配

         不产生逃逸的方法内,对象会部分被分配到栈上面 

参考博客:JVM的mixed mode_yzpyzp的博客-CSDN博客

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

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

相关文章

LVS负载均衡群集部署——NAT模式

LVS负载均衡群集部署——NAT模式 一、企业群集应用概述1、群集概述2、解决方法3、根据集群针对的目标差异分类 二、负载均衡群集架构三、LVS 的三种工作模式1、NAT 地址转换2、TUN IP隧道 IP Tunnel3、DR 直接路由 Direct Routing 四、LVS的负载调度算法五、ipvsadm工具六、NAT…

linux shell pgrep命令使用方法(pgrep指令)获取进程号、统计进程数量(学会区分Linux进程进程名)

文章目录 问题背景pgrep指令help文档使用示例1. 列出匹配进程的PID和进程名称&#xff08;-l&#xff09;&#xff08;默认只能从进程名的子集字符串匹配&#xff0c;如果要使用完整进程名的子集字符串匹配&#xff0c;请加-f参数&#xff0c;下同&#xff09;2. 列出匹配进程的…

生成古风少女图片【InsCode Stable Diffusion美图活动一期】

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​ 目录 写在前面 Stable Diffusion 模型在线使用地址&#xff1a; 工具介绍 一.如何使用S…

【NLP】用python实现文本转语音处理

一、说明 介绍一款python调用库&#xff0c;离线软件包pyttsx3 API&#xff0c;它能够将文字转化成语音文件。Python 中有多种 API 可用于将文本转换为语音。pyttsx3 是一个非常易于使用的工具&#xff0c;可将输入的文本转换为音频。与其它类似的库不同&#xff0c;它可以离线…

第十八章 MobileViT网络详解

系列文章目录 第一章 AlexNet网络详解 第二章 VGG网络详解 第三章 GoogLeNet网络详解 第四章 ResNet网络详解 第五章 ResNeXt网络详解 第六章 MobileNetv1网络详解 第七章 MobileNetv2网络详解 第八章 MobileNetv3网络详解 第九章 ShuffleNetv1网络详解 第十章…

Qt/C++编写跨平台的推流工具(支持win/linux/mac/嵌入式linux/安卓等)

一、前言 跨平台的推流工具当属OBS最牛逼&#xff0c;功能也是最强大的&#xff0c;唯一的遗憾就是多路推流需要用到插件&#xff0c;而且CPU占用比较高&#xff0c;默认OBS的规则是将对应画布中的视频画面和设定的音频一起重新编码再推流&#xff0c;意味着肯定占用不少CPU资…

passware kit forensic使用

一、从外部注册表文件提取密码 适用于不联网的情况下&#xff0c;例如2023盘古石杯的NAS取证 找到Windows/System32/config并在本地打开 将路径填充到config folder中 跑出来了John电脑对应的密码是paofen&#xff0c;NAS的密码是P88w0rd 后续遇见再补

【运维知识进阶篇】zabbix5.0稳定版详解7(zabbix分布式监控:使用场景+功能详解+快速部署+基本使用)

如果你有几百上千台客户端的数据需要上报给zabbix服务端&#xff0c;即便是你做了主动注册&#xff0c;监控项目主动式&#xff0c;那服务端压力还是会很大&#xff0c;所以我们可以考虑zabbix分布式监控。 zabbix proxy可以代替zabbix server收集性能和可用性数据&#xff0c…

6.用python写网络爬虫,表单交互

在前面几章中&#xff0c;我们下载的静态网页总是返回相同的内容。而在本章中&#xff0c;我们将与网页进行交互 根据用户输入返回对应的内容。本章将包含如下几个主题&#xff1a; 发送 POST 请求提交表单&#xff1a; 使用 cookie 登录网站&#xff1a; 用于简化表单提交的高…

Scala的foldLeft与foldRight详解

foldLeft与foldRight是特质TraversableOnce定义的高阶函数&#xff0c;直译过来为向左折叠和向右折叠。具体实现如下摘出的代码所示&#xff1a; trait TraversableOnce[A] extends Any with GenTraversableOnce[A] {deprecated("Use foldLeft instead of /:", &quo…

小波变换笔记

突然变化的图像或信号 小波变换 高带宽&#xff1f; 放缩和时延 放缩因子和频率成正比 小波在频域中具有带通特性 Cf 中心频率 s 小波刻度 \delta t 采样间隔 时延 我们需要移动小波&#xff0c;以便使其和信号中寻找的特征对齐 时频分析时域频率成分滤波 连续小波变换 C…

iview tree树形控件多选,自定义内容

项目中需要一个iview框架的树形控件,需要里面包含以下功能 1、控件宽度可展开,可缩小2、树形控件可搜索,并且定位到搜索的节点3、控件可以一键勾选,一键取消4、控件图标自定义5、 点击最后一个节点时可以进入到二级节点,点击上一节点可返回完整代码:listToTree文件 效果图: 具…