JVM性能监控与调优——命令行工具

文章目录

  • 1、概述
  • 2、jps:查看正在运行的Java进程
  • 3、jstat:查看JVM统计信息
  • 4、jinfo:实时查看和修改JVM配置参数
  • 5、jmap:导出内存映像文件和内存使用情况
  • 6、jhat:JDK自带堆分析工具
  • 7、jstack:打印JVM中线程快照
  • 8、jcmd:多功能命令行
  • 9、jstatd:远程主机信息收集
  • 10、小结

性能问题是软件工程师在日常工作中需要经常面对和解决的问题,在用户体验至上的今天,解决好应用的性能问题能带来非常大的收益。工欲善其事,必先利其器,想要解决性能相关问题,必须要有比较好的性能诊断工具。Java作为最流行的编程语言之一,应用的性能诊断一直受到业界广泛关注。造成Java应用出现性能问题的因素非常多,例如线程控制、磁盘读写、数据库访问、网络I/O、垃圾收集等。想要定位这些问题,一款优秀的性能诊断工具必不可少,就好比中医、西医看病,中医讲究的是望、闻、问、切,西医则是借助各种检查仪器。

1、概述

JDK本身已经集成了很多诊断工具。在大家刚接触Java学习的时候,最先了解的两个命令就是javac和java,但是除此之外,还有一些其他工具可以使用,可是并非所有的程序员都了解其他命令行程序的作用,接下来我们一起看看其他命令行程序的作用。进入到安装JDK的bin目录,会发现还有一系列辅助工具。这些辅助工具用来获取目标JVM不同方面、不同层次的信息,帮助开发人员很好地解决Java应用程序的一些疑难杂症。Mac系统bin目录的内容如下图所示:
在这里插入图片描述
Windows系统bin目录的内容如下图所示:
在这里插入图片描述
虽然在Windows系统下都是exe格式的可执行文件。但事实上,它们只是Java程序的一层包装,其真正实现是在tools.jar中,如下图所示。以jps工具为例,在控制台执行jps命令和执行java -classpath %Java_HOME%/lib/tools.jar sun.tools.jps.Jps命令是等价的,即jps.exe只是这个命令的一层包装。下面介绍一些常用的命令工具。
在这里插入图片描述

2、jps:查看正在运行的Java进程

jps(JVM Process Status Tool)命令用于查看系统内所有的JVM进程,可根据参数选项指定是否显示JVM的执行主类[包含main()方法的类],以及进程的本地JVMID(Local Virtual Machine Identifier),对于本地JVM进程来说,进程的本地JVMID与操作系统的进程ID是一致的。简单来说,就是Java提供的一个显示当前所有Java进程pid的命令,和Linux系统里的ps命令很相似,ps命令主要是用来显示当前系统的进程情况,比如查看进程列表和进程ID。在日常工作中,此命令也是最常用的命令之一。

jps的基本使用语法如下:

     jps  [ options ] [ hostid ]

1、jps命令[options]选项说明:
在这里插入图片描述
2、[hostid]说明:
hostid表示目标主机的主机名或IP地址,如果省略该参数,则目标主机为本地主机。如果想要远程监控主机上的Java程序,需要安装jstatd。对于网络安全要求非常严格的场所,需要自定义策略文件来满足对特定的主机或网络的访问,但是这种技术容易受到IP地址欺诈攻击。如果由于安全问题无法通过定制的策略文件处理,那么最安全的操作是在主机本地使用jstat和jps工具。

3、使用案例:
Linux上启动Tomcat(一种Web应用服务器),然后在Linux上面使用ps命令查看Tomcat进程ID使用,如下所示:

     ps -ef | grep"tomcat"

运行结果如下图所示:
在这里插入图片描述
可以看到进程ID是1224。使用jps -l命令查看,如下图上所示:
在这里插入图片描述

3、jstat:查看JVM统计信息

jstat(JVM Statistics Monitoring Tool)用于收集JVM各方面的运行数据,显示本地或远程JVM进程中的类装载、内存、垃圾收集、JIT编译等运行数据。在没有图形用户界面时,只提供了纯文本控制台环境的服务器上,它是运行期定位JVM性能问题的首选工具。常用于检测垃圾回收问题以及内存泄漏问题。它的功能非常强大,可以通过它查看堆信息的详细情况。

jstat的基本使用语法如下:

     jstat -<option>[-t] [-h<lines>] <vmid>[<interval>[<count>]]

使用下面的命令可以查看jstat相关参数:

     jstat -h 或 jstat -help

1、[options]选项说明
在这里插入图片描述
2、[-t]参数说明
[-t]参数可以在输出信息前加上一个Timestamp列,显示程序的运行时间。可以比较Java进程的启动时间以及总GC时间(GCT列),或者两次测量的间隔时间以及总GC时间的增量,来得出GC时间占运行时间的比例。如果该比例超过20%,则说明目前堆的压力较大;如果该比例超过90%,则说明堆里几乎没有可用空间,随时都可能抛出OOM异常。

3、[-h]参数说明
[-h]参数可以在周期性数据输岀时,输出设定的行数的数据后输出一个表头信息。

4、[interval]参数说明
[interval]参数用于指定输出统计数据的周期,单位为毫秒,简单来说就是查询间隔时间。

5、[count]参数说明
[count]用于指定查询的总次数。

6、使用案列
由于jstat参数选项比较多,这里只列举一个启动了Tomcat的Linux服务器案例,查看其监视状态,命令如下所示。
在这里插入图片描述
运行结果如下图所示:
在这里插入图片描述
运行结果的各列表示的含义如下表所示:
在这里插入图片描述
jstat还可以用来判断是否出现内存泄漏,步骤如下:

  • (1)在长时间运行的Java程序中,可以运行jstat命令连续获取多行性能数据,并取这几行数据中OU列(即已占用的老年代内存)的最小值。
  • (2)每隔一段较长的时间重复一次上述操作,获得多组OU最小值。如果这些值呈上涨趋势,则说明该Java程序的老年代内存已使用量在不断上涨,这意味着无法回收的对象在不断增加,因此很有可能存在内存泄漏。

4、jinfo:实时查看和修改JVM配置参数

jinfo(Configuration Info for Java)可用于查看和调整JVM的配置参数。在很多情况下,Java应用程序不会指定所有的JVM参数。而此时,开发人员可能不知道某一个具体的JVM参数的默认值。在这种情况下,可能需要通过查找文档获取某个参数的默认值。这个查找过程可能是非常艰难的。但有了jinfo工具,开发人员可以很方便地找到JVM参数的当前值。上面讲解的jps -v命令虽然可以查看JVM启动时显示指定的参数列表,但是如果想要知道未被显示指定的参数的系统默认值,就需要用到jinfo工具了。

第二个作用就是在程序运行时修改部分参数,并使之立即生效。并非所有参数都支持动态修改,只有被标记为manageable的参数可以被实时修改。其实,这个修改能力是极其有限的,使用下面的命令查看被标记为manageable的参数。

     java -XX:+PrintFlagsFinal -version | grep manageable

运行结果如下图所示:
在这里插入图片描述
jinfo的基本使用语法如下:

     jinfo  [ options ] pid

1、[ options ]选项说明
jinfo工具options主要选项如下表所示:
在这里插入图片描述

2、pid说明
Java进程ID,必须要加上。

3、使用案例
由于jinfo可以查看JVM配置信息,也可用于调整JVM的配置参数,下面分两类案例分别讲解如何使用。

4、jinfo用于查看JVM配置信息案例
在这里插入图片描述
程序很简单,只需要保证程序在执行状态即可。首先使用jps命令查看进程ID,如下所示:

     #查看进程ID
     jps -l

执行结果如下:

     C:\Users\Administrator>jps -l
     15008 com.yang.ScannerTest
     14820 sun.tools.jps.Jps

上面出现两个结果,ScannerTest程序的进程ID是15008,另外一个进程ID表示jps命令本身的进程。下面使用jinfo命令来查看JVM配置参数,命令如下:
(1)根据进程ID查询全部参数和系统属性:

     #查看全部参数和系统属性,
     jinfo  15008

因篇幅所限,只展示部分结果,如下所示:
在这里插入图片描述
结果中含有Java系统属性(System Properties)和JVM参数(VM Flags)。

(2)根据进程ID查询系统属性(选项:-sysprops)命令如下:

     #查看系统属性
     jinfo -sysprops 15008

运行结果如下,篇幅原因只展示部分结果,如下所示:
在这里插入图片描述
通过Java代码获取系统属性如下代码清单所示:
在这里插入图片描述
运行结果如下图所示:
在这里插入图片描述
通过比较两者结果一致。

(3)查看全部JVM参数配置(选项:flags),命令如下:

     #查看全部JVM参数配置
     jinfo -flags 15008

运行结果如下图所示:
在这里插入图片描述
可以看到里面包含初始堆大小、最大堆大小等参数配置。

(4)查看某个Java进程的具体参数的值(选项:-flag name),命令如下:

     #查看JVM是否使用了ParallelGC垃圾收集器
     jinfo –flag UseParallelGC 15008

运行结果如下图所示:
在这里插入图片描述
可以看到结果为-XX:+UseParallelGC,其中UseParallelGC前面的“+”表示已经使用,如果没有使用的话,用“-”表示。也可以查看某个参数的具体数值,比如查看新生代对象晋升到老年代对象的最大年龄,命令如下:

     #新生代对象晋升到老年代对象的最大年龄
     jinfo -flag MaxTenuringThreshold 15008

在这里插入图片描述
从结果可知新生代对象晋升到老年代对象的最大年龄是15。

5、jinfo用于修改JVM配置信息案例
(1)开启或者关闭对应名称的参数(-flag [±]name)(或者称为修改布尔类型的参数)。

首先查看是否开启输出GC日志的参数,如果GC日志参数是开启状态,那么使用jinfo命令关闭;如果GC日志参数是关闭状态,那么使用jinfo命令开启,命令如下:
在这里插入图片描述
对于布尔类型的JVM参数,不仅可以使用-flag [±]name的形式来进行值的改变,也可以使用-flag name=value的形式修改运行时的JVM参数。但是对value赋值必须是1或者0,1表示“+”,0表示“-”,如下所示:
在这里插入图片描述

(2)修改对应名称的参数(-flag name=value)(或者称为修改非布尔类型的参数)。

修改非布尔类型MaxHeapFreeRatio的值,命令如下:
在这里插入图片描述
运行结果如下图所示:
在这里插入图片描述
除了使用jinfo查看JVM配置参数之外,还有如下方式:
在这里插入图片描述
java -XX:+PrintFlagsInitial执行结果如下,展示部分结果:
在这里插入图片描述
java -XX:+PrintFlagsFinal执行结果如下,展示部分结果:
在这里插入图片描述
输出结果中包含五列。第一列表示参数的数据类型,第二列表示参数名称,第四列表示参数的值,第五列表示参数的类别。第三列“=”是参数的默认值,而“:=”表示参数被用户或者JVM赋值了。可以通过“java -XX:+PrintFlagsFinal |grep":="”命令查看哪些参数是被用户或者JVM赋值的。java -XX:+PrintFlagsInitial只展示了第三列为“=”的参数。

java -XX:+PrintCommandLineFlags执行结果如下,该参数输出被用户或者JVM设置过的详细的-XX参数的名称和值:

     -XX:InitialHeapSize=268435456
     -XX:MaxHeapSize=4294967296
     -XX:+PrintCommandLineFlags
     -XX:+UseCompressedClassPointers
     -XX:+UseCompressedOops
     -XX:+UseParallelGC

该参数的结果是java -XX:+PrintFlagsFinal的结果中带有“:=”的部分参数。可以通过该命令快捷地查看修改过的参数。

5、jmap:导出内存映像文件和内存使用情况

jmap(JVM Memory Map)用于生成JVM的内存转储快照,生成heapdump文件且可以查询finalize执行队列,以及Java堆与元空间的一些信息。jmap的作用并不仅仅是为了获取dump文件(堆转储快照文件,二进制文件),它还可以获取目标Java进程的内存相关信息,包括Java堆各区域的使用情况、堆中对象的统计信息、类加载信息等。

开发人员可以在控制台中输入命令“jmap-help”,查阅jmap工具的具体使用方式和标准选项配置。jmap的基本使用语法如下:
在这里插入图片描述
1、[ options ]选项说明
jmap工具[options]主要选项如下表所示:
在这里插入图片描述
这些参数和Linux下输入显示的命令多少会有一些不同,也受JDK版本的影响。其中选项-dump、-heap、-histo是开发人员在工作中使用频率较高的指令。

2、使用案例
(1)-dump选项:导出内存映像文件。

一般来说,使用jmap指令生成dump文件的操作算得上是最常用的jmap命令之一,将堆中所有存活对象导出至一个文件之中。执行该命令,JVM会将整个Java堆二进制格式转储到指定filename的文件中。live子选项是可选的,如果指定了live子选项,堆中只有存活的对象会被转储。

通常在写dump文件前会触发一次Full GC,所以dump文件里保存的都是Full GC后留下的对象信息。由于生成dump文件比较耗时,因此大家需要耐心等待,尤其是大内存镜像生成dump文件需要耗费更长的时间来完成。

如果想要浏览dump文件,大家可以使用jhat(Java堆分析工具)读取生成的文件,也可以使用可视化工具进行解读,比如MAT内存分析工具。获取dump文件有手动获取和自动获取两种方式。

手动获取的意思是当发现系统需要优化或者需要解决内存问题时,需要开发者主动执行jmap命令,导出dump文件,手动获取命令如下:

     #手动获取堆内存全部信息
     jmap -dump:format=b,file=<filename.hprof><pid>
     #手动获取堆内存存活对象全部信息
     jmap -dump:live,format=b,file=<filename.hprof><pid>

代码清单如下所示,往堆内存中存放数据,然后导出dump文件。
在这里插入图片描述
运行程序,最终该程序会产生内存溢出,在执行过程中使用上述命令导出dump文件即可,运行结果如下图所示:
在这里插入图片描述
上述命令中,file表示指定文件目录,这里将文件放到D盘根目录,10692表示Java进程ID,结果如下图所示,dump1.hprof就是导出的结果文件。
在这里插入图片描述
当程序发生内存溢出退出系统时,一些瞬时信息都随着程序的终止而消失,而重现OOM问题往往比较困难或者耗时。若能在OOM时,自动导出dump文件就显得非常迫切。可以配置JVM参数“-XX:+HeapDumpOnOutOfMemoryError:”使程序发生OOM时,导出应用程序的当前堆快照。

依然使用上面代码,在启动程序之前,在idea中添加如下JVM参数配置:

     -Xms60m
     -Xmx60m
     -XX:+HeapDumpOnOutOfMemoryError
     -XX:HeapDumpPath=d:/autoDump.hprof

添加参数如下图所示:
在这里插入图片描述
启动程序,运行结果如下图所示:
在这里插入图片描述
从结果可知,程序发生了内存溢出,此时dump文件自动生成到目标目录中,如下图所示:
在这里插入图片描述
(2)-heap选项:显示堆内存相关信息
命令如下:

     #1520表示当前进程ID
     jmap -heap 1520

运行结果如下:
在这里插入图片描述
打印heap的概要信息、GC使用的算法、heap的配置和使用情况,可以判断当前堆内存使用情况以及垃圾回收情况。

可以看到最大堆大小为60MB,和前面的VM配置信息一致;新生代大小等于Eden区加From区加To的大小,总共为20MB,符合新生代和老年代比例大小为2:1;老年代大小为40MB,老年代使用率达到了99.53%,说明老年代空间是不足的。

(3)-hiso选项:显示堆中对象的统计信息:

     #1520表示当前进程ID
     jmap -histo 1520

运行结果如下,由于篇幅原因,展示部分结果:
在这里插入图片描述
上面结果中,instances表示当前的实例数量;bytes表示对象占用的内存大小;classs name表示类名,按照内存大小逆序排列。

(4)-permstat选项:
该选项主要以ClassLoader为口径输出永久代的内存状态信息,仅对Linux和solaris平台有效。

(5)-finalizerinfo选项。
该选项主要用来显示F-Queue中等待Finalize线程执行finalize方法的对象,就是说查看堆积在finalizer队列中的对象。仅对Linux和solaris平台有效。

(6)-F选项
该选项用于当JVM进程对-dump选项没有任何响应时,可使用此选项强制执行生成dump文件。仅对Linux和solaris平台有效。

由于jmap将访问堆中的所有对象,为了保证在此过程中不被应用线程干扰,jmap需要借助安全点机制,让所有线程不改变堆中数据的状态。也就是说,由jmap导出的堆快照必定是安全点位置的。这可能导致基于该快照的分析结果存在偏差。例如,假设在编译生成的机器码中,某些对象的生命周期在两个安全点之间,那么:live选项将无法探知到这些对象。另外如果某个线程长时间无法跑到安全点,jmap将一直等待下去。与前面讲的jstat不同,垃圾收集器会主动将jstat所需要的摘要数据保存至固定位置中,而jstat只需要直接读取即可。

6、jhat:JDK自带堆分析工具

jhat(JVM Heap Analysis Tool)命令一般与jmap命令搭配使用,用于分析jmap生成的dump文件(堆转储快照)。jhat内置了一个微型的HTTP/HTML服务器,生成dump文件的分析结果后,用户可以在浏览器中查看分析结果。

使用了jhat命令,就启动了一个http服务,端口是7000,即通过访问http://localhost:7000/就可以在浏览器中查看结果。jhat命令在JDK9中已经被删除,官方建议用VisualVM代替。实际工作中一般不会直接在生产服务器使用jhat分析dump文件。

7、jstack:打印JVM中线程快照

jstack(JVM Stack Trace)用于生成JVM指定进程当前时刻的线程快照(Thread Dump),方便用户跟踪JVM堆栈信息。线程快照就是当前JVM内指定进程的每一条线程正在执行的方法堆栈的集合。

生成线程快照的作用是可用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等问题,这些都是导致线程长时间停顿的常见原因。当线程出现停顿时,就可以用jstack显示各个线程调用的堆栈情况。

在线程快照中,有下面几种状态,如下表所示:
在这里插入图片描述
其中线程的Deadlock、Waiting on condition、Waiting on monitor entry以及Blocked状态需要在分析线程栈的时候重点关注。

jstack的基本使用语法如下:

     jstack [ option ] <pid>

1、[ options ]选项说明
jstack工具[options]主要选项如下表所示:
在这里插入图片描述
2、使用案例
代码清单如下演示了线程死锁,使用jstack命令观察线程状态。
在这里插入图片描述
上面例子很简单,启动了两个线程,分别获取对方的资源,如此造成死锁。下面启动程序,使用jstack命令查看线程状态,命令如下,其中1776是程序的进程ID。

     jstack 1776

运行结果如下:
在这里插入图片描述
从上面结果中可以发现,Thread-1线程和Thread-0线程互相等待对方的资源,问题代码出现“com.yang.ThreadDeadLock$2.run()”行。在死锁情况出现时,可以很方便地帮助定位到问题。也可以通过Thread.getAllStackTraces()方法获取所有线程的状态,代码清单如下所示:
在这里插入图片描述
运行结果如下图所示,可以看到各个线程的状态:
在这里插入图片描述

8、jcmd:多功能命令行

在JDK1.7以后,新增了一个命令行工具jcmd。它是一个多功能的工具,可以用来实现前面除了jstat之外所有命令的功能,比如用它来导出堆、内存使用、查看Java进程、导出线程信息、执行GC、JVM运行时间等。jcmd拥有jmap的大部分功能,并且官方也推荐使用jcmd命令代替jmap命令。

至于jstat的功能,虽然jcmd复制了jstat的部分代码,并支持通过PerfCounter.print子命令来打印所有的Performance Counter,但是它没有保留jstat的输出格式,也没有重复打印的功能。

jcmd的基本使用语法如下表所示:
在这里插入图片描述

9、jstatd:远程主机信息收集

之前的指令只涉及监控本机的Java应用程序,而在这些工具中,一些监控工具也支持对远程计算机的监控(如jps、jstat)。为了启用远程监控,则需要配合使用jstatd工具。

命令jstatd是一个RMI服务端程序,它的作用相当于代理服务器,建立本地计算机与远程监控工具的通信。jstatd服务器将本机的Java应用程序信息传递到远程计算机。执行原理如下图所示:
在这里插入图片描述

直接打开jstatd服务器可能会抛出访问拒绝异常,这是因为jstatd程序没有足够的权限,如下图所示:
在这里插入图片描述

10、小结

介绍了JDK自带的命令行工具及其常用参数。当Java应用和服务出现莫名的卡顿、CPU飙升等问题时,通过JDK自带的状态监控命令和图形化工具,可以非常方便地分析对应进程的JVM状态,进而定位问题并解决问题。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第一个Swift程序

要创建第一个Swift项目,请按照以下步骤操作: 打开Xcode。如果您没有安装Xcode,可以在App Store中下载并安装它。在Xcode的欢迎界面上,选择“Create a new Xcode project”(创建新Xcode项目)。在模板选择界面上,选择“App”(应用程序)。在应用模板选择界面上,选择“Si…

【静态分析】静态分析笔记01 - Introduction

参考&#xff1a; BV1zE411s77Z [南京大学]-[软件分析]课程学习笔记(一)-introduction_南京大学软件分析笔记-CSDN博客 ------------------------------------------------------------------------------------------------------ 1. program language and static analysis…

【JavaWeb】Jsp基本教程

目录 JSP概述作用一个简单的案例&#xff1a;使用JSP页面输出当前日期 JSP处理过程JSP 生命周期编译阶段初始化阶段执行阶段销毁阶段案例 JSP页面的元素JSP指令JSP中的page指令Include指令示例 taglib指令 JSP中的小脚本与表达式JSP中的声明JSP中的注释HTML的注释JSP注释 JSP行…

llinux进程控制

学习进程创建,fork/vfork 学习到进程等待 学习到进程程序替换, 微型shell&#xff0c;重新认识shell运行原理 学习到进程终止,认识$? fork函数 在linux中fork函数时非常重要的函数&#xff0c;它从已存在进程中创建一个新进程。新进程为子进程&#xff0c;而原进程为父进程…

PostgreSQL入门到实战-第十五弹

PostgreSQL入门到实战 PostgreSQL数据过滤(八)官网地址PostgreSQL概述PostgreSQL中LIKE命令理论PostgreSQL中LIKE命令实战更新计划 PostgreSQL数据过滤(八) 如何使用PostgreSQL LIKE运算符基于模式查询数据。 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容不一…

Commitizen:规范化你的 Git 提交信息

简介 在团队协作开发过程中&#xff0c;规范化的 Git 提交信息可以提高代码维护的效率&#xff0c;便于追踪和定位问题。Commitizen 是一个帮助我们规范化 Git 提交信息的工具&#xff0c;它提供了一种交互式的方式来生成符合约定格式的提交信息。 原理 Commitizen 的核心原…

人工智能分类算法概述

文章目录 人工智能主要分类算法决策树随机森林逻辑回归K-均值 总结 人工智能主要分类算法 人工智能分类算法是用于将数据划分为不同类别的算法。这些算法通过学习数据的特征和模式&#xff0c;将输入数据映射到相应的类别。分类算法在人工智能中具有广泛的应用&#xff0c;如图…

每日一题(leetcode2529):正整数和负整数的最大计数--二分法

因为需要O&#xff08;logn&#xff09;的复杂度&#xff0c;所以考虑使用二分法&#xff0c;先找到负数里面的最大下标&#xff08;初始值定为-1&#xff09;&#xff0c;再找到第一个正数的下标&#xff08;初始值定为数组长度值&#xff09;。最后求出个数并进行比较即可。 …

操作系统的基础知识:操作系统的特征:并发,共享,虚拟,异步

操作系统的特性&#xff1a; 1.并发 并发:指两个或多个事件在同一时间间隔内发生。这些事件宏观上是同时发生的&#xff0c;但微观上是交替注意&#xff1a;并行:指两个或多个事件在同一时刻同时发生。 操作系统的并发性指计算机系统中“同时”运行着多个程序&#xff0c;这…

【Entity Framework】聊聊EF中键

【Entity Framework】聊聊EF中键 文章目录 【Entity Framework】聊聊EF中键一、概述二、配置主键2.1 约定配置主键2.2 单个属性配置为实体主键2.3 组合主键 三、主键名称四、键类型和值五、备用键 一、概述 键用作每个实体实例的唯一标识符。EF中的大多数实体都有一个键&#…

langchain-chatchat加载Azure Open AI

1.找到knowledge_base_chat.py文件中的get_ChatOpenAI函数 2.按crtl进入get_ChatOpenAI函数位置 3.注释原先的get_ChatOpenAI函数&#xff0c;修改成以下内容&#xff1a; def get_ChatOpenAI(model_name: str,temperature: float,streaming: bool True,callbacks: List[Ca…

5款最值得推荐的电脑监控软件丨高人气甄选

在企业和学校等场所&#xff0c;电脑监控软件被广泛应用于员工或学生的行为管理。 通过监控软件&#xff0c;管理者可以了解员工或学生的学习和工作情况&#xff0c;及时发现并纠正不当行为&#xff0c;提高工作效率和学习效果。同时&#xff0c;这类软件还可以用于保护企业机…

13 指针(上)

指针是 C 语言最重要的概念之一&#xff0c;也是最难理解的概念之一。 指针是C语言的精髓&#xff0c;要想掌握C语言就需要深入地了解指针。 指针类型在考研中用得最多的地方&#xff0c;就是和结构体结合起来构造结点(如链表的结点、二叉树的结点等)。 本章专题脉络 1、指针…

SQL注入的其他攻击思路方法与Python脚本设计思路

SQL注入的其他攻击思路方法与Python脚本设计思路 也是很早就写了&#xff0c;也备个份吧 注意&#xff1a;在接下来的攻击方式中&#xff0c;由于实现的条件较为苛刻&#xff0c;并且需要较高权限&#xff0c;有的师傅又称之为高权限攻击 利用文件读取进行SQL注入 上一篇文章提…

mysql8主从复杂原理分析

MySQL 复制&#xff08;Replication&#xff09; 是官方提供的主从复制&#xff08;源到副本的复制&#xff09;方案&#xff0c;用于将一个 MySQL 的实例同步到另一个实例中。 这是使用最广泛的容灾方案&#xff08;重点掌握&#xff09;。 复制&#xff08;Replication&…

编译器如何理解C++的指针和引用?

初学引用时&#xff0c;往往很难真正理解引用&#xff0c;它与指针究竟有什么区别和联系。下面我们不妨看看编译器如何理解引用和指针的。 一.函数通过指针传参 1.1 示例代码 #include <iostream>using namespace std;void swap(int *x,int *y)//指针传参 {int tmp;t…

【机器学习300问】66、ReLU激活函数相对于Sigmoid和Tanh激活函数的优点是什么?ReLU它有局限性吗?如何改进?

一、ReLU相对于Sigmoid和Tanh的优点 &#xff08;1&#xff09;计算效率高 ReLU函数数学形式简单&#xff0c;仅需要对输入进行阈值操作&#xff0c;大于0则保留&#xff0c;小于0则置为0。Sigmoid和Tanh需要指数运算但ReLU不需要。所以相比之下它会更快&#xff0c;降低了神经…

agi入门-大模型开发基础

AGI(Artifical General Inteligence)的到来还有多久&#xff1f; 乐观预测&#xff1a;明年主流预测&#xff1a;3-5年悲观预测&#xff1a;10年 AGI时代&#xff0c;AI无处不在&#xff0c;相关从来者将如何分&#xff1f; AI使用者&#xff1a;使用别人开发的AI产品AI产品…

让链接直接唤起应用,Xinstall助力提升用户体验

在移动互联网时代&#xff0c;应用程序已成为我们日常生活的重要组成部分。然而&#xff0c;有时候我们在浏览器或其他应用中看到一个有趣的链接&#xff0c;想要打开对应的应用查看更多内容&#xff0c;却需要手动复制链接&#xff0c;再打开应用粘贴查看。这样的操作繁琐且不…

Backtrader 量化回测实践(6)——量化回测评价工具Quantstats

Backtrader 量化回测实践&#xff08;6&#xff09;——量化回测评价工具Quantstats 1.概述 Quantstats是用于量化金融分析和投资组合优化的Python库。该库提供了各种工具&#xff0c;可从不同来源获得金融数据&#xff0c;进行技术和基本分析&#xff0c;并创建和测试投资策…