当前位置: 首页 > news >正文

jvm优化

1.jvm组成

什么是jvm,java是跨平台语言,对不同的平台(windos,linux),有不同的jvm版本。jvm屏蔽了平台的不同,提供了统一的运行环境,让java代码无需考虑平台的差异。

jdk包含jre包含jvm

java跨平台原理,通过jvm屏蔽系统差异

为什么要优化jvm?

所谓优化就是配置一些jvm参数,让jvm运行时使用这些参数,让在jvm运行的程序更加良好的运。

行。

默认配置,资源得不到最优分配。

jvm组成

本地方法接口:接入其他语言lib库,native

类加载器:加载类

执行引擎:编译加载过来的类

运行时数据区:程序在运行过程中产生的数据,就在这个地方。

java中所谓的垃圾,就是用来的对象要被回收。

类加载子系统

通过类加载器,把相关类的字节码加载进去。

类加载过程

1.加载:找到字节码文件,读取到内存中,类的加载方式分为隐式加载和显式加载、new,就是隐式加载到jvm。显式加载,通过调用class.forName,加载到内存中去。

2.验证:验证此文件是不是一个真的字节码文件,后缀名是可以改,内在身份标识是不会变的。java验证很严格,通过130多页的验证过程的内容。

3.准备:为类中static修饰的变量分配内存空间并设置初始值,static 123 是初始化才会赋值,准备阶段主要是分配内存。static修饰上还加了final,那么它会在准备赋值。

static 修饰变量分配内存空间,并赋值为0或null

如果static int a =123

final修饰,准备阶段就赋值

4.解析:解析阶段会将java代码中的符号引用替换为直接引用,全限定名(符号引用)找类。

直接引用:

符号引用:

5.初始化:为变量赋初始值,static 初始化

2.类加载机制

类加载器有四种,前三种必然存在

启动类加载器,加载jre_home  lib下文件加载,就是jdk中文件夹中lib的文件

扩展类加载器 加载jdk ext下的

应用程序类加载器:加载classpath下的,我们的代码,还有依赖jar都是在classpath

自定义加载器

类加载器,双亲委派机制

先去爷爷那里找,去爸爸那里找,最好自己找。

就是启动类加载器那里找,然后扩展类加载器找,最好应用程序类加载器。

目的是为了让我们不去覆盖java提供的类,三方可以覆盖。2

项目中导入的三方依赖和自己的类都在classpath下,所以我们可以覆盖第三方依赖。之所以让我们的类可以覆盖三方导入的类,是因为可以让我们扩展第三方的类。

比如有的包有bug,自己修一修。

3.运行时数据区

1.7和1.8数据区组成不一样

堆线程共享区:堆

线程隔离区

区别是什么:1.8以后,方法区被元空间替代,没有方法区了,元空间使用本地内存而不是jvm内存。

程序计数器:是线程私有的,指定线程顺序,会记录你当前执行到行数,以及下一句。确定指令的执行顺序

java虚拟机栈:java虚拟机栈也是线程私有的,每个线程分配一个虚拟机栈,每个虚拟机栈有若干的栈帧,每一个栈帧对应一个方法。

一个线程一个栈

每经过一个方法,放一个栈帧

栈帧:一个方法就是一个栈帧。

先进后出,压栈,从上往下。 

局部变量表:

操作数栈

本地方法栈:本地方法执行的本地方法,虚拟机栈执行的是java方法,本地是native 方法。

方法区 永久代

1.7把常量池和静态变量放到堆

1.8 类和静态变量到元空间

元空间占本地内存不占jvm内存。

永久代:永远不会被回收

去永久代的原因:

字符串存在永久代,容易出性能问题和内存溢出。

类和方法信息的比较难确定其大小

永久代会为gc带来不必要的复杂度

堆内存

堆和方法区

都是线程共享的

堆分为新生代,老年代,

新生代:

一个eden,两个survivor,from    survivor区,to survivor区

eden:刚刚new出来的,一般短命,一次垃圾回收就gg

可能每用完,移到其他区域,历经15次垃圾回收,则放到老年代区

这是常规情况

已经满了的话,直接放入老年代。

堆内存一般存对象和数组,被线程共享。

4.元空间

方法区主要用于存储虚拟机加载的类信息、常量、静态变量,以及编译器编译后的代码等数据,所以方法区溢出的原因就是没有足够的内存来存放这些数据。

常量池在JDK1.6存放在方法区中;
常量池在JDK1.8存放在元空间中

1.8后

不存在永久代方法区,替代它的一块空间为元空间,使用本地内存,可以自己指定元空间大小。

5.jvm内存溢出

堆内存溢出,堆中放对象,数组,不断创建你对象或数组,且让这些对象,数组不会被垃圾回收。那么堆中内存就有可能会溢出。

栈溢出

不停创建线程,让栈的数量溢出       创建多个线程

让栈里面的空间溢出。 不停调用方法

6.执行引擎

即使编译器:把字节码编译成机械码 和垃圾回收器

javac:把源文件编译为字节码文件

明确一个概念,只认0和1组成的命令集称之为机械码,

垃圾回收

判断是不是垃圾,选择垃圾回收期进行回收,使用垃圾回收机制回收垃圾。

1.垃圾标记算法——识别垃圾

判断对象是否已死有引用计数算法和可达性分析算法。

1.1引用计数算法

引用计数器

每个对象都有计数器,每次引用加一,为零没有人引用,就会被回收。

看起来很简单,但是没用,对象间相互引用,这时他们没有用处了。

可达性分析算法

GC roots,垃圾回收的起点,虚拟机栈中本地变量表中引用的对象,调用链能达到根。达不到根就是死的。

finalize:对象覆盖了finalize,还没有被调用,如果里面方法和根有关联,就可以拯救自己。

JVM 之 虚拟机栈 之 局部变量表(详细)_jvm局部变量表-CSDN博客

常用垃圾回收算法:

7.1标记清除算法,

7.2标记和清除效率不高,会产生大量不连续的内存碎片。

7.3 复制算法,把内存分为大小相等的两块,每次存储只用其中一块,当这一块用完了,就把存活的对象全部复制到另一块上,同时把使用过的这块内存空间全部清理掉,往复循环。

用一半之后,把存活的对象移到另外一半,然后用另外一半,然后清理这一半,相当于分成了两半使用。

缺点:实际可用内存为原来一半。

7.4标记整理算法

对可用对象进行标记,然后所以被标记对象向一端移动,最后清除可用对象边界意外的内存。

7.5分代收集算法

新生代,老年代

新生代一般使用复制算法,存活比较短

老年代标记清除,标记整理。

Minor gc full gc

在说这两种回收的区别之前,我们先来说一个概念,“Stop-The-World”。如字面意思,每次垃圾回收的时候,都会将整个JVM暂停,回收完成后再继续。如果一边增加废弃对象,一边进行垃圾回收,完成工作似乎就变得遥遥无期了。

minor gc 一般暂停时间很短

full gc  一般是老年代的回收,伴随至少一次的minor GC ,新生代和老年代都回收,老年代,暂停时间比较长,因为是标记回收法,通常是minor gc的时间十倍以上。

所以我们尽量minor gc,不要fullgc,经常暂停,给用户很卡的感觉。

GC的流程

大多数情况下,新的对象都分配在Eden区,当Eden区没有空间进行分配时,将进行一次Minor GC,清理Eden区中的无用对象。清理后,Eden和From Survivor中的存活对象如果小于To Survivor的可用空间则进入To Survivor,否则直接进入老年代);Eden和From Survivor中还存活且能够进入To Survivor的对象年龄增加1岁(虚拟机为每个对象定义了一个年龄计数器,每执行一次Minor GC年龄加1),当存活对象的年龄到达一定程度(默认15岁)后进入老年代,可以通过-XX:MaxTenuringThreshold来设置年龄的值。

每经过一次minor gc,年龄加一,达到15次,进入老年代

数据太大青年区去放不了,直接老年代

如果老年代没有连续大空间,则会进行full gc。m gc之前,预测老年代内存不够,full gc

java代码,system。gc,手动进行垃圾回收,不建议,尽量让虚拟机自己的gc策略。

GC 发展阶段:Serial(串行) => Parallel(并行)=> CMS(并发)=> G1 => ZGC

常见垃圾收集器

新生代收集器 Serial、ParNew、Parallel Scavenge

老年代收集器 Serial Old、CMS、Parallel Old

堆内存垃圾收集器

新生代“:

parNew cms 是一对 停顿少 回收多(前面是新生代,后面是老年区)

parallel scavenge   parallel old  追求吞吐量,停顿时间长,回收短(前面是新生代,后面是老年区)

jdk1.8和jdk1.7用的就是这个。

jvm优化

系统运行日志

jvm内存优化,通过一些工具或日志

用jps -l,查看进程

jstat  监视虚拟机信息

jmap 查看堆内存情况

分析堆转储快照

有个java可视化工具

jvm优化实战

jvm优化,就是设置堆内存大小和栈内存大小

开发时

通过右上角改

idea开发环境下,进行统一修改

上线的时候,直接写参数

公司里面一般都有一些启动项目的参数模版,拷贝过去先运行。

网上找一个差不多的

为什么要设置这个数,参数是怎么设置,我们有参数模版,每次启动拷贝过来运行即可。没有模版,网上找了个差不多的。

相关文章:

jvm优化

1.jvm组成 什么是jvm,java是跨平台语言,对不同的平台(windos,linux),有不同的jvm版本。jvm屏蔽了平台的不同,提供了统一的运行环境,让java代码无需考虑平台的差异。 jdk包含jre包含…...

网络安全——防御课实验二

在实验一的基础上,完成7-11题 拓扑图 7、办公区设备可以通过电信链路和移动链路上网(多对多的NAT,并且需要保留一个公网IP不能用来转换) 首先,按照之前的操作,创建新的安全区(电信和移动)分别表示两个外网…...

朴素模式匹配算法与KMP算法(非重点)

目录 一. 朴素模式匹配算法1.1 什么是字符串的匹配模式1.2 朴素模式匹配算法1.3 通过数组下标实现朴素模式匹配算法 二. KMP算法2.1 算法分析2.2 用代码实现(只会出现在选择题,考察代码的概率不大) 三. 手算next数组四. KMP算法的进一步优化4…...

[k8s源码]2.CURD deployment

加载kubernetes配置 使用 clientcmd方法,是通过"k8s.io/client-go/tools/clientcmd"包加载的。这个函数返回的是config和error两个值。可以看到返回的config是一个指针变量。 func clientcmd.BuildConfigFromFlags(masterUrl string, kubeconfigPath str…...

使用base64通用文件上传

编写一个上传文件的组件 tuku,点击图片上传后使用FileReader异步读取文件的内容&#xff0c;读取完成后获得文件名和base64码&#xff0c;调用后端uploadApi,传入姓名和base64文件信息&#xff0c;后端存入nginx中&#xff0c;用于访问 tuku.ts组件代码&#xff1a; <templa…...

Python深度学习

python深度学习&#xff0c;python代码定制&#xff0c; 可做创新点 创新思路 代码改进跑通 深度学习 Python代跑时间序列预测 分析 代码编写 python编程 深度学习算法 自然语言处理 神经网络跑通指导 爬虫调试代做 项目指导 定制帮做 改进 提升 创新 优化 Python Matlab C…...

django报错(三):No crontab program或got an unexpected keyword argument ‘user’

Crontab是linux系统上的定时管理模块&#xff0c;简单配置&#xff0c;灵活使用。但是要在windows使用必须借助Cygwin等虚拟工具&#xff0c;否则会报错“No crontab program”。如下图&#xff1a; python-crontab是其提供了python模块对crontab的访问&#xff0c;即可以通过p…...

数据库(创建数据库和表)

目录 一&#xff1a;创建数据库 二&#xff1a;创建表 2.1&#xff1a;创建employees表 2.2&#xff1a;创建orders表 2.3&#xff1a;创建invoices表 一&#xff1a;创建数据库 mysql> create database mydb6_product; Query OK, 1 row affected (0.01 sec) mysql&g…...

Log4j的原理及应用详解(一)

本系列文章简介&#xff1a; 在软件开发的广阔领域中&#xff0c;日志记录是一项至关重要的活动。它不仅帮助开发者追踪程序的执行流程&#xff0c;还在问题排查、性能监控以及用户行为分析等方面发挥着不可替代的作用。随着软件系统的日益复杂&#xff0c;对日志管理的需求也日…...

ubuntu系统Docker常用命令

1.查看docker是否开机启动 sudo systemctl list-unit-files | grep enable|grep docker 2.设置开机启动 sudo systemctl enable docker 3.关闭docker开机启动 sudo systemctl disable docker 4.开启docker服务 sudo service docker start 5.关闭docker服务 sudo servi…...

韦东山嵌入式linux系列-驱动设计的思想(面向对象/分层/分离)

1 面向对象 字符设备驱动程序抽象出一个 file_operations 结构体&#xff1b; 我们写的程序针对硬件部分抽象出 led_operations 结构体。 2 分层 上下分层&#xff0c;比如我们前面写的 LED 驱动程序就分为 2 层&#xff1a; ① 上层实现硬件无关的操作&#xff0c;比如注册…...

0/1背包

0/1背包 背包问题是DP最经典的类型之一&#xff0c;而0/1背包是最经典最基础的背包问题。 背包体积为 V V V&#xff0c; n n n种物品&#xff0c;每种物品只有1个&#xff0c;第 i i i种物品对应体积为 c i c_i ci​&#xff0c;价值为 w i w_i wi​&#xff0c;怎样装填能使…...

Linux的进程和权限的基本命令

目录 基本命令 man find date cal du ln exit grep 基本命令-帮助查询&#xff1a; wc cat more less head tail echo alias unalias 基本命令-进程管理&#xff1a; ps kill top 操作系统负载查看 用户分类&#xff1a; 程序用户 普通用户&#x…...

鼠标录制工具怎么挑选?9款电脑鼠标录制工具分享(2024)

你知道鼠标录制工具吗&#xff1f;鼠标录制工具通过记录和回放用户的操作&#xff0c;帮助自动化重复性任务&#xff0c;提高工作效率和精确性。它可以帮助用户简化很多繁琐的操作步骤&#xff0c;非常适合运用在电脑自动化任务、游戏自动化中&#xff0c;给大家整理了2024年9款…...

C1W4.LAB.Vector manipulation+Hash functions and multiplanes

理论课&#xff1a;C1W4.Machine Translation and Document Search 文章目录 Python 中的矢量操作Transforming vectorsExample 1Example 2 Frobenius Norm Hash functions and multiplanesBasic Hash tablesPlanesHash Function with multiple planesRandom PlanesDocument v…...

YOLOv8改进 | 检测头 | 融合渐进特征金字塔的检测头【AFPN4】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…...

数据采集监控平台:挖掘数据价值 高效高速生产!

在当今数字化的时代&#xff0c;数据已成为企业非常宝贵的资产之一。然而&#xff0c;要充分发挥数据的潜力&#xff0c;离不开一个强大的数据采集监控平台&#xff0c;尤其是生产制造行业。它不仅是数据的收集者&#xff0c;更是洞察生产的智慧之眼&#xff0c;高效高速处理产…...

【算法笔记自学】第 9 章 提高篇(3)——数据结构专题(2)

9.1树与二叉树 #include <cstdio>int main() {int n, m;scanf("%d%d", &n, &m);printf(n m 1 ? "Yes" : "No");return 0; } 9.2二叉树的遍历 #include <cstdio> #include <vector> using namespace std;const int…...

Objective-C 中字符串的保存位置

在 Objective-C 中&#xff0c;字符串常量和动态创建的字符串&#xff08;例如通过 stringWithFormat:、initWithString: 等方法创建的字符串&#xff09;在内存中保存的位置一样么 &#xff1f; 在 Objective-C 中&#xff0c;字符串常量和动态创建的字符串在内存中的保存位置…...

git 想要创建一个新的本地分支并检出远程分支的内容

如果你想要创建一个新的本地分支并检出远程分支的内容&#xff1a; git checkout -b feature-branch origin/feature-branch feature-branch 是你在本地创建的新分支名&#xff0c;origin/feature-branch 是远程分支的引用。 根据你检出的远程分支的名字而定 不知道名称的时…...

C语言学习笔记[24]:循环语句while②

getchar()的使用场景 int main() {char password[20] {0};printf("请输入密码&#xff1a;");//输入 123456 后回车scanf("%s", passwoed);//数组名本身就是数组地址printf("请确认密码&#xff1a;Y/N");int ch getchar();if(Y ch)printf(&…...

安全运营概述

安全运营概述 概述安全运营的工作对内安全运营工作对外安全运营工作品牌建设 概述 安全是一个过程&#xff0c;安全是靠运营出来的&#xff0c;公司会不断的有新业务的变更&#xff0c;新产品的发布&#xff0c;新版本的升级&#xff0c;技术架构的升级&#xff0c;底层系统的…...

spring-cloud和spring-cloud-alibaba的关系

首先Spring Cloud 是什么&#xff1f; Spring Cloud是一系列框架的有序集合&#xff0c;它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发。Spring Cloud提供了微服务架构开发所需的多种组件和工具&#xff0c;如服务发现注册、配置中心、消息总线、负载均…...

持续集成06--Jenkins构建触发器

前言 在持续集成&#xff08;CI&#xff09;的实践中&#xff0c;构建触发器是自动化流程中不可或缺的一环。它决定了何时启动构建过程&#xff0c;从而确保代码变更能够及时地得到验证和反馈。Jenkins&#xff0c;作为业界领先的CI/CD工具&#xff0c;提供了多种构建触发器选项…...

根据视图矩阵, 恢复相机的世界空间的位置

根据视图矩阵, 恢复相机的世界空间的位置 一、方法1 glsl 实现: // 从本地局部坐标系(相机空间) 到 世界空间的旋转变换 mat3 getLocal2WorldRotation() {mat3 world2localRotation mat3(viewMatrix[0].xyz,viewMatrix[1].xyz,viewMatrix[2].xyz);return inverse(world2loca…...

使用pytest-playwright截图和录制视频并添加到Allure报告

一、依赖环境 python, version==3.9.5 pytest-playwright, version==0.5.1 allure-pytest, version==2.13.5 pytest, version==6.2.5 allure, version==2.22.0pytest-playwright支持如下命令行参数: Playwright:--browser={chromium,firefox,webkit}Browser engine which …...

pytorch GPU cuda 使用 报错 整理

GPU 使用、报错整理 1. 使用指定GPU&#xff08;单卡&#xff09;1.1 方法1&#xff1a;os.environ[CUDA_VISIBLE_DEVICES]1.2 方法2&#xff1a;torch.device(cuda:2)1.3 报错1&#xff1a;RuntimeError: CUDA error: invalid device ordinal CUDA kernel errors might be asy…...

python + Pytest + requests 的接口自动化步骤

pythonpytestrequestallureyaml接口自动化测试项目实战 开发环境准备 1. jdk 下载 Java官网下载地址&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 安装&#xff1a; https://blog.csdn.net/VA_AV/article/details/138…...

基于若依的ruoyi-nbcio流程管理系统修正自定义业务表单的回写bug

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; h…...

GD32 MCU上电跌落导致启动异常如何解决

大家是否碰到过MCU上电过程中存在电源波动或者电压跌落导致MCU启动异常的问题&#xff1f;本视频将会为大家讲解可能的原因以及解决方法&#xff1a; GD32 MCU上下电复位波形如下图所示&#xff0c;上电过程中如果存在吃电的模块&#xff0c;比如wifi模块/4G模块/开启某块电路…...