Java虚拟机的优化方法

随着时间的推移,许多优化已经提高了 JVM 的性能。然而,尽管 Java 通常是第一个成功实现它们的虚拟机,但它们也经常被用于其他类似的平台。

1.即时编译

早期的 JVM 总是解释 Java 字节码。在普通应用程序中,Java 的性能损失比 C 大 10 到 20 倍。为了解决这个问题,Java 1.1 引入了即时 (JIT) 编译器。由于编译成本高,Java 1.2 引入了一个名为 HotSpot 的附加系统,并在 Java 1.3 中将其设为默认系统。使用这个框架,Java 虚拟机会不断分析程序性能,找出经常或重复执行的热点。然后针对这些热点进行优化,从而以最小的开销实现高性能执行,以降低性能要求不高的代码的开销。一些基准测试显示,通过这种方式,速度提高了 10 倍。但是,由于时间限制,编译器无法完全优化程序,因此生成的程序比本机代码替代方案慢。

2.自适应优化

自适应优化是计算机科学中的一种方法,它根据当前执行配置文件对程序的各个部分进行动态重新编译。通过简单的实现,自适应优化器可以简单地在即时编译和解释指令之间进行权衡。在另一个层面上,自适应优化可以利用本地数据条件来优化分支并使用内联扩展。

像 HotSpot 这样的 Java 虚拟机还可以对以前经过 JIT 的代码进行反优化。这允许执行积极(且可能不安全)的优化,同时仍然能够稍后对代码进行反优化并返回到安全路径。

3.垃圾收集

1.0 和 1.1 Java 虚拟机 (JVM) 使用标记清除收集器,这可能会在垃圾收集后对堆进行碎片化。从 Java 1.2 开始,JVM 改为使用分代收集器,其碎片整理行为要好得多。现代 JVM 使用各种方法,进一步提高了垃圾收集性能。

4.指针压缩

压缩的 Oops 允许 Java 5.0+ 使用 32 位引用寻址最多 32 GB 的堆。Java 不支持访问单个字节,仅支持默认为 8 字节对齐的对象。因此,堆引用的最低 3 位将始终为 0。通过将 32 位引用的分辨率降低到 8 字节块,可寻址空间可以增加到 32 GB。与使用 64 位引用相比,这显著减少了内存使用,因为 Java 使用引用的数量远远超过 C++ 等某些语言。Java 8 支持更大的对齐,例如 16 字节对齐,以支持使用 32 位引用最多为64 GB。

5.分割字节码验证

在执行类之前,Sun JVM 会验证其 Java 字节码。此验证是延迟执行的:仅在加载并准备使用特定类时才加载和验证类的字节码,而不是在程序开始时。但是,由于 Java 类库也是常规 Java 类,因此在使用时也必须加载它们,这意味着 Java 程序的启动时间通常比 C++ 程序等更长。

一种名为分时验证的方法,最早在 Java Platform, Micro Edition (J2ME) 中引入,自 Java 版本 6 以来在 JVM 中使用。它将 Java 字节码的验证分为两个阶段:

  • 设计时 - 将类从源代码编译为字节码时
  • 运行时 - 加载类时。

实际上,此方法通过捕获 Java 编译器对类流的了解并使用类流信息概要注释已编译的方法字节码来工作。这不会使运行时验证变得简单得多,但确实允许一些捷径。

6.逃逸分析和锁粗化

Java 能够在语言级别管理多线程。多线程允许程序同时执行多个进程,从而提高在具有多个处理器或核心的计算机系统上运行的程序的性能。此外,多线程应用程序即使在执行长时间运行的任务时也可以保持对输入的响应。

但是,使用多线程的程序需要特别注意线程之间共享的对象,当其中一个线程使用共享方法或块时,锁定对共享方法或块的访问。由于所涉及的底层操作系统级操作的性质,锁定块或对象是一项耗时的操作。

由于 Java 库不知道哪些方法将被多个线程使用,因此标准库在多线程环境中总是在需要时锁定块。

在 Java 6 之前,虚拟机总是在程序要求时锁定对象和块,即使不存在对象被两个不同的线程同时修改的风险。例如,在本例中,每次添加操作之前都会锁定一个本地 Vector,以确保它不会被其他线程修改(Vector 是同步的),但由于它严格地位于方法的本地,因此这是不必要的:

从 Java 6 开始,代码块和对象仅在需要时才被锁定,因此在上述情况下,虚拟机根本不会锁定 Vector 对象。

自版本 6u23 以来,Java 包含对逃逸分析的支持。

7.寄存器分配改进

在 Java 6 之前,客户端虚拟机中的寄存器分配非常原始(它们不能跨块存在),这在处理器寄存器较少的 CPU 设计中是一个问题,例如 x86。如果没有更多寄存器可用于操作,则编译器必须从寄存器复制到内存(或从内存复制到寄存器),这需要时间(寄存器的访问速度要快得多)。但是,服务器虚拟机使用了颜色图分配器,因此不存在此问题。

Sun 的 JDK 6 引入了寄存器分配的优化;然后可以跨块使用相同的寄存器(如果适用),从而减少对内存的访问。这导致一些基准测试中报告的性能提升了约 60%。

8.类数据共享

类数据共享(Sun 称之为 CDS)是一种减少 Java 应用程序启动时间并减少内存占用的机制。安装 JRE 时,安装程​​序会将系统 JAR 文件(包含所有 Java 类库的 JAR 文件,称为 rt.jar)中的一组类加载到私有内部表示中,并将该表示转储到称为“共享存档”的文件中。在后续 JVM 调用期间,此共享存档将进行内存映射,从而节省加载这些类的成本,并允许在多个 JVM 进程之间共享这些类的大部分 JVM 元数据。

对于小型程序,启动时间的相应改进更为明显。

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

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

相关文章

静态网页实现-人脸识别-案例(web)

🤳人脸识别(web) 基于开源大模型,将人脸识别功能整合到网页中,提供用户友好的界面和强大的功能。 核心功能 人脸轮廓识别: 通过深度学习算法,精确识别人脸的轮廓,包括眼睛、鼻子、嘴巴等关键部…

Sql注入漏洞汇总-上

产生的原因 当web应用向后台数据库传递SQL语句进行数据库操作时,如果对用户输入的参数没有经过严格的过滤处理,那么攻击者就可以构造特殊的SQL语句,带入数据库中进行查询,从而导致数据的泄露或者修改。 02 分类 1、按照查询的类型分类 数字型 select * from user whe…

在QML中调用 C++ 函数的方法(四)

文章目录 前言一、qml 和 c++ 交互的官方文档介绍二、QML 中调用 C++ 实现的函数的方法1. Exposing Attributes of C++ Types to QML1.1 暴露 Properties1.2 暴露 Methods(槽函数和Q_INVOKABLE 修饰的函数)1.3 暴露 Signals2. Defining QML Types from C++3. 代码实例3.1 创建一…

【OpenHarmony】ArkTS 语法基础 ③ ( @Component 自定义组件生命周期回调函数 | @Entry 页面生命周期回调函数 )

文章目录 一、ArkTS Component 自定义组件生命周期1、自定义组件生命周期2、aboutToAppear 函数执行时机和作用3、aboutToDisappear 函数执行时机和作用4、代码示例 二、ArkTS Entry 页面生命周期1、Entry 页面生命周期2、onBackPress 和 onPageHide 回调函数无关联 三、代码示…

文化若想挣钱,真的很可怕吗?

文化若想挣钱,真的很可怕吗? 近日,我看到受人尊敬的静思有我先生的一个音频作品《会挣钱,遇上有文化,这个地方很可怕》,把这个标题在网上搜一搜,在它下面就跟着有这样一篇文章--商人不可怕&…

vscode 1.85安装remote-ssh后左侧没有图标

vscode安装remote-ssh插件后左侧没有图标。 解决方法 想要左侧有图标,是另一个插件起作用:Remote Explorer 但是这个插件最新版需要1.87,可以switch to Pre-release version之后就能用了。 其实,最后再switch to Release Versio…

PHP网络编程是什么:深入探索其四个方面、五个方面、六个方面与七个方面的核心奥秘

PHP网络编程是什么:深入探索其四个方面、五个方面、六个方面与七个方面的核心奥秘 PHP网络编程,这个看似简单的概念,实则蕴含着丰富的内涵和无尽的探索空间。它不仅是现代网络应用开发的重要基石,更是无数开发者实现创意与梦想的…

动静态库【Linux】

文章目录 静态库的打包动态库的打包 静态库的打包 把我们提供的方法,给别人用: 1、把源文件直接给别人 2、把源代码打包成库库.h 例如 ;有a.c b.c c.c d.c ,四个.c文件 , 将a.c 形成a.o ,b.c形成b.o c.c形成c.o d.c形成d.o文件,…

JS片段:生成 UUID

Hi,这里是松桑,每天学习一个 JS 片段,涨涨🧀!今天带来的是如何生成 UUID,UUID作为全局唯一标识,使用常见广泛,包括分布式系统、数据库主键、会话标识、消息队列、日志追踪等等。 什么…

【前端Vue3】——JQuery知识点总结(超详细)

🎼个人主页:【Y小夜】 😎作者简介:一位双非学校的大二学生,编程爱好者, 专注于基础和实战分享,欢迎私信咨询! 🎆入门知识专栏:🎇【MySQL&#…

【力扣刷题 动态规划】LeetCode 139 单词拆分、LeetCode 300 最长递增子序列 ✌

文章目录 1. 单词拆分2. 最长递增子序列 1. 单词拆分 题目链接 &#x1f34e; 解题思路&#xff1a; class Solution {bool dp[310] {false};public:bool wordBreak(string s, vector<string>& wordDict) {unordered_set<string> myset;for(auto& str :…

《欢乐钓鱼大师》新手攻略大全!新手逆袭之路!

《欢乐钓鱼大师》是一款趣味十足的模拟钓鱼游戏&#xff0c;适合各类玩家&#xff0c;从钓鱼新手到钓鱼高手都能在游戏中找到乐趣。为了帮助新手玩家更快地掌握游戏技巧&#xff0c;提高钓鱼水平&#xff0c;我们准备了一些实用的攻略和技巧&#xff0c;帮助大家轻松入门&#…

PDF 文件的解析

1、文本 PDF 的解析 1.1、文本的提取 进行文本提取的 Python 库包括&#xff1a;pdfminer.six、PyMuPDF、PyPDF2 和 pdfplumber&#xff0c;效果最好的是 PyMuPDF&#xff0c;PyMuPDF 在进行文本提取时能够最大限度地保留 PDF 的阅读顺序&#xff0c;这对于双栏 PDF 文件的抽…

【0286】Postgres内核 shared buffer pool 初始化原理

0. shared buffer pool 附&#xff1a;shared buffer初始化后&#xff0c;BufferDescriptors中变量bufferdesc的值如下面文件所示&#xff1a; Postgres shared buffer pool初始化过程日志

vue-router 源码分析——1. 路由匹配

这是对vue-router 3 版本的源码分析。 本次分析会按以下方法进行&#xff1a; 按官网的使用文档顺序&#xff0c;围绕着某一功能点进行分析。这样不仅能学习优秀的项目源码&#xff0c;更能加深对项目的某个功能是如何实现的理解。这个对自己的技能提升&#xff0c;甚至面试时…

MyBatis3.4全集笔记

MyBatis 1. MyBatis 简介 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code&#xff0c;并且改名为MyBatis 。2013年11月迁移到Github。 iBATIS一词来源于“internet”和“abatis”的组合&#xff0c;是一个基于Ja…

Sed流编辑器总结

sed 是 Unix 和 Linux 系统中的一个强大的流编辑器。它用于对文本进行基本的修改和处理。以下是关于 sed 的详细解说&#xff0c;包括其基本语法&#xff0c;常见用法和一些高级用法。 基本语法 sed [选项] 命令 输入文件常见选项 -e&#xff1a;指定要执行的 sed 命令。-f&a…

SpringSecurity6从入门到实战之SpringSecurity整合自动装配详解(源码级讲解,耐心看完)

SpringSecurity6从入门到实战之SpringSecurity整合自动装配详解 这里我先引出问题然后再来一步步进行剖析,SpringSecurity到底是如何实现引入依赖后所有请求都需要进行认证并且会弹出login登录表单页面. 接下来会对SpringBoot的自动装配进行详解,SpringSecurity也是通过自动装配…

AI绘画Stable Diffusion 制作幻术光影字:使用Brightness亮度控制模型,超简单!

大家好&#xff0c;我是灵魂画师向阳。 今天给大家分享的教程是利用AI工具Stable Diffusion 制作光影文字。这是一种通过模拟自然光线照射和阴影效果&#xff0c;使文字看起来具有立体感和逼真感的设计风格。 它的主要目的是让文字自然的融合在场景中。 先来看组实例图。 …

【机器学习数据挖掘】基于ARIMA 自回归积分滑动平均模型的销售价格库存分析报告 附完整python代码

资源地址&#xff1a;Python数据分析大作业 4000字 图文分析文档 销售分析 完整python代码 ​ 完整代码分析 同时销售量后1000的sku品类占比中&#xff08;不畅销产品&#xff09;如上&#xff0c;精品类产品占比第一&#xff0c;达到66.7%&#xff0c;其次是香化类产品&#…