JVM 调优

news2024/11/18 3:00:43

      大部分的情况都是由于企业内部代码逻辑不合理导致。

JVM内部性能优化

  • 栈上分配
  • 方法内联
  • JVM的自适应调整

JVM改错

  • 大并发内存不足
  • OOM 内存泄漏
  • GC频繁
  • CPU飙升

JVM的调优的原则是让你各项指标尽可能的利用到你硬件的性能瓶颈。

JVM的性能优化可以分为代码层面和非代码层面。

在代码层面,大家可以结合字节码指令进行优化,比如一个循环语句,可以将循环不相关的代码提 取到循环体之外,这样在字节码层面就不需要重复执行这些代码了。

在非代码层面,一般情况可以从内存、  gc以及cpu占用率等方面进行优化。

注意,JVM调优是一个漫长和复杂的过程,而在很多情况下,JVM是不需要优化的,因为JVM本身已经做了很多的内部优化操作。

一,JVM参数

1,标准参数

-version 
-help 
-server 
-cp

2,非标准参数[ -X ]

也就是在JDK各个版本中可能会变动
-Xint 解释执行 
-Xcomp 第一次使用就编译成本地代码 
-Xmixed 混合模式,JVM自己来决定

3,非标准化参数 [ -XX ]

相对不稳定,主要用于JVM调优和Debug
a.Boolean类型 
格式:-XX:[+-]<name> +或-表示启用或者禁用name属性 
比如:-XX:+UseConcMarkSweepGC 表示启用CMS类型的垃圾回收器 -XX:+UseG1GC 表示启用G1类型的垃圾回收器 
b.非Boolean类型 
格式:-XX<name>=<value>表示name属性的值是value 
比如:-XX:MaxGCPauseMillis=500

4,其他参数

-Xms1000M等价于-XX:InitialHeapSize=1000M 
-Xmx1000M等价于-XX:MaxHeapSize=1000M 
-Xss100等价于-XX:ThreadStackSize=100

所以这块也相当于是-XX类型的参数

5,查看参数

java -XX:+PrintFlagsFinal -version > flags.txt

值得注意的是"="表示默认值,":="表示被用户或JVM修改后的值

要想查看某个进程具体参数的值,可以使用jinfo
一般要设置参数,可以先查看一下当前参数是什么,然后进行修改

6,设置参数的常见方式

  • 开发工具中设置比如IDEA,eclipse
  • 运行jar包的时候:java -XX:+UseG1GC xxx.jar
  • web容器比如tomcat,可以在脚本中的进行设置
  • 通过jinfo实时调整某个java进程的参数(参数只有被标记为manageable的flags可以被实时修改)

7,实践和单位换算

(1)设置堆内存大小和参数打印 -Xmx100M -Xms100M -XX:+PrintFlagsFinal 
(2)查询+PrintFlagsFinal的值 :=true 
(3)查询堆内存大小MaxHeapSize := 104857600 
(4)换算 104857600(Byte)/1024=102400(KB) 102400(KB)/1024=100(MB) 
(5)结论 104857600是字节单位
1Byte(字节)=8bit(位)
1KB=1024Byte(字节)
1MB=1024KB
1GB=1024MB
1TB=1024GB

8,常用参数含义

-XX:CICompilerCount=3
最大并行编译数
如果设置大于1,虽然编译速度 会提高,但是同样影响系统稳定 性,会增加JVM崩溃的可能 

-XX:InitialHeapSize=100M 
初始化堆大小
简写-Xms100M 

-XX:MaxHeapSize=100M 
最大堆大小 
简写-Xms100M 

-XX:NewSize=20M 
设置年轻代的大小 

-XX:MaxNewSize=50M 
年轻代最大大小 

-XX:OldSize=50M 
设置老年代大小 

-XX:MetaspaceSize=50M 
设置方法区大小

-XX:MaxMetaspaceSize=50M
方法区最大大小 

-XX:+UseParallelGC
使用UseParallelGC 
新生代,吞吐量优先

-XX:+UseParallelOldGC 
使用UseParallelOldGC 
老年代,吞吐量优先 

-XX:+UseConcMarkSweepGC 
使用CMS 
老年代,停顿时间优先 

-XX:+UseG1GC 
使用G1GC 
新生代,老年代,停顿时间优先

-XX:NewRatio 
新老生代的比值
比如-XX:Ratio=4,则表示新生代: 老年代=1:4,也就是新生代占整 个堆内存的1/5 

-XX:SurvivorRatio 
两个S区和Eden区的比值 
比如-XX:SurvivorRatio=8,也就 是(S0+S1):Eden=2:8,也就是一 个S占整个新生代的1/10 

-XX:+HeapDumpOnOutOfMemoryError 
启动堆内存溢出打印 
当JVM堆内存发生溢出时,也就 是OOM,自动生成dump文件 

-XX:HeapDumpPath=heap.hprof 
指定堆内存溢出打印目录 
表示在当前目录生成一个 heap.hprof文件 

-XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps 
-XX:+PrintGCDateStamps 
-Xloggc:g1- gc.log 
打印出GC日志 
可以使用不同的垃圾收集器,对 比查看GC情况 

-Xss128k 
设置每个线程的堆栈大小
经验值是3000-5000最佳 

-XX:MaxTenuringThreshold=6 
提升年老代的最大临界值 
默认值为 15 

-XX:InitiatingHeapOccupancyPercent 
启动并发GC周期时堆内存使用占比 
G1之类的垃圾收集器用它来触发 并发GC周期,基于整个堆的使用 率,而不只是某一代内存的使用比. 值为 0 则表示”一直执行GC循环”. 默认值为 45. 

-XX:G1HeapWastePercent 
允许的浪费堆空间的占比
默认是10%,如果并发标记可回 收的空间小于10%,则不会触发 MixedGC。 

-XX:MaxGCPauseMillis=200ms 
G1最大停顿时间 
暂停时间不能太小,太小的话就 会导致出现G1跟不上垃圾产生的 速度。最终退化成Full GC。所以 对这个参数的调优是一个持续的 过程,逐步调整到最佳状态。 

-XX:ConcGCThreads=n 
并发垃圾收集器使用的线程数量 
默认值随JVM运行的平台不同而 不同 

-XX:G1MixedGCLiveThresholdPercent=65 
混合垃圾回收周期中要包括的旧区 
域设置占用率阈值 
默认占用率为 65%

-XX:G1MixedGCCountTarget=8 
设置标记周期完成后,对存活数据 上限为 G1MixedGCLIveThresholdPercent 的旧区域执行混合垃圾回收的目标次数
默认8次混合垃圾回收,混合回 收的目标是要控制在此目标次数以内 

-XX:G1OldCSetRegionThresholdPercent=1 
描述Mixed GC时,Old Region被加 入到CSet中
默认情况下,G1只把10%的Old Region加入到CSet中

二,常用命令

1,jps

查看java进程
The jps command lists the instrumented Java HotSpot VMs on the target system. The
command is limited to reporting information on JVMs for which it has the access
permissions.

 2,jinfo

(1)实时查看和调整JVM配置参数

The jinfo command prints Java configuration information for a specified Java
process or core file or a remote debug server. The configuration information
includes Java system properties and Java Virtual Machine (JVM) command-line
flags.
(2)查看用法

jinfo -flag name PID 查看某个java进程的name属性的值

jinfo -flag MaxHeapSize PID 
jinfo -flag UseG1GC PID

(3)修改 

参数只有被标记为manageable的flags可以被实时修改

jinfo -flag [+|-] PID jinfo -flag <name>=<value> PID

(4)查看曾经赋过值的一些参数

jinfo -flags PID

 3,jstat

(1)查看虚拟机性能统计信息

The jstack command prints Java stack traces of Java threads for a specified Java process, core file, or remote debug server.

(2) 查看类装载信息

jstat -class PID 1000 10   查看某个java进程的类装载信息,每1000毫秒输出一次,共输出10次

(3)查看垃圾收集信息 

jstat -gc PID 1000 10

4jstack 

  (1)查看线程堆栈信息

The jstack command prints Java stack traces of Java threads for a specified Java process, core file, or remote debug server.

(2)用法

jstack PID

 (3)排查死锁案例

//运行主类
public class DeadLockDemo {
    public static void main(String[] args) {
        DeadLock d1 = new DeadLock(true);
        DeadLock d2 = new DeadLock(false);
        Thread t1 = new Thread(d1);
        Thread t2 = new Thread(d2);
        t1.start();
        t2.start();
    }
}
//定义锁对象
class MyLock {
    public static Object obj1 = new Object();
    public static Object obj2 = new Object();
}


//死锁代码
class DeadLock implements Runnable {
    private boolean flag;
    DeadLock(boolean flag) {
        this.flag = flag;
    }
    public void run() {
            if (flag) {
                while (true) {
                    synchronized(MyLock.obj1) {
                        System.out.println(Thread.currentThread().getName() + "----if获
                            得obj1锁 ");
                            synchronized(MyLock.obj2) {
                                System.out.println(Thread.currentThread().getName() + "--- - if获得obj2锁 ");
                                }
                            }
                        }
                    } else {
                        while (true) {
                            synchronized(MyLock.obj2) {
                                System.out.println(Thread.currentThread().getName() + "----否则
                                    获得obj2锁 ");
                                    synchronized(MyLock.obj1) {
                                        System.out.println(Thread.currentThread().getName() + "--- - 否则获得obj1锁 ");

                                        }
                                    }
                                }
                            }
                        }

jstack分析

把打印信息拉到最后可以发现 

5,jmap

  (1)生成堆转储快照

The jmap command prints shared object memory maps or heap memory details of a specified process, core file, or remote debug server.

(2)打印出堆内存相关信息

jmap -heap PID

jinfo -flag UsePSAdaptiveSurvivorSizePolicy 35352
-XX:SurvivorRatio=8

 (3)  dump出堆内存相关信息

jmap -dump:format=b,file=heap.hprof PID

 (4)要是在发生堆内存溢出的时候,自动dump出该文件

一般在开发中,  JVM参数可以加上下面两句,这样内存溢出时,会自动dump出该文件

​​​​​​​-XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=heap.hprof

三,内存

正常情况下不需要设置,那如果是促销或者秒杀的场景呢

台机器配置2c4G,以每秒3000笔订单为例,整个过程持续60

1,内存溢出(OOM)

一般会有两个原因:

(1)大并发情况下

(2)内存泄露导致内存溢出

2,大并发[秒杀]

浏览器缓存、本地缓存、验证

CDN静态资源服务

集群+负载均衡

动静态资源分离、限流[基于令牌桶、漏桶算法]

用级别缓存、接口防刷限流、队列、  Tomcat性能优化

步消息中间件

Redis数据对象缓存

分布式锁、数据库

5钟之内没有支付,取消订单、恢复库存等

3,内存泄露导致内存溢出

ThreadLocal的内存泄露,最终导致内存溢出

public class TLController {

    @RequestMapping(value = "/tl")
    public String tl(HttpServletRequest request) {
        ThreadLocal < Byte[] > tl = new ThreadLocal < Byte[] > ();
        // 1MB
        tl.set(new Byte[1024 * 1024]);
        return "ok";
    }
}

(1)  top命令查

top
top -Hp PID

(2)  jstack查看线程情况,发现没有死锁或者IO阻塞的情况

jstack PID
java -jar arthas.jar   --->   thread

(3)查看堆内存的使用,发现堆内存的使用率已经高达88.95%

jmap -heap PID
java -jar arthas.jar   --->   dashboard

(4)此时可以大体判断出来,发生了内存泄露从而导致的内存溢出,那怎么排查呢?​​​​​​​

jmap -histo:live PID | more

获取到jvm.hprof文件,上传到指定的工具分析,比如heaphero.io
获取使用Memory Analyzer Tool 进行分析

四,垃圾收集器的选择

吞吐量和停顿时间

  • 停顿时间
垃圾收集器进行垃圾回收终端应用执行响应的时间
  • 吞吐量
运行用户代码时间/(运行用户代码时间+垃圾收集时间)
这两个指标也是评价垃圾回收器好处的标准。
如何选择合适的垃圾收集器
 
https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html#
sthref28
  • 优先调整堆的大小让服务器自己来选择
  • 如果内存小于100M,使用串行收集器
  • 如果是单核,并且没有停顿时间要求,使用串行或JVM自己选
  • 如果允许停顿时间超过1秒,选择并行或JVM自己选
  • 如果响应时间最重要,并且不能超过1秒,使用并发收集器

对于G1收集

JDK 7开始使用,JDK 8非常成熟,JDK 9默认的垃圾收集器,适用于新老生代。
是否使用G1收集器?
(1)50%以上的堆被存活对象占用
(2)对象分配和晋升的速度变化非常大
(3)垃圾回收时间比较长
G1中的RSet

全称Remembered Set,记录维护Region中对象的引用关系

试想,在G1垃圾收集器进行新生代的垃圾收集时,也就是Minor GC,假如该对象被老年代的Region中所引用,这时候新生代的该对象就不能被回收,怎么记录呢?
不妨这样,用一个类似于hash的结构,key记录region的地址,value表示引用该对象的集合,这样就能知道该对象被哪些老年代的对象所引用,从而不能回收
如何开启需要的垃圾收集器
(1)串行 
    -XX:+UseSerialGC 
    -XX:+UseSerialOldGC 
(2)并行(吞吐量优先): 
    -XX:+UseParallelGC 
    -XX:+UseParallelOldGC 
(3)并发收集器(响应时间优先) 
    -XX:+UseConcMarkSweepGC 
    -XX:+UseG1GC

五,G1优化

是否选用G1

官网  https://docs.oracle.com/javase/8/docs/technotes/guides/vm/G1.html#use_cases

(1) 50%以上的堆被存活对象占用

(2) 对象分配和晋升的速度变化非常

(3) 垃圾回收时间比较长

    (1)使用G1GC垃圾收集器: -XX:+UseG1GC

修改配参数,获取到gc日志,使用GCViewer分析吞吐量和响应时间

Throughput

99.16%

Min Pause

0.00016s

Max Pause 0.0137s

Avg Pause

0.00559s

GC count

12

   (2)调整内存大小再获取gc日志分析

比如置堆内存的大小,获取到gc日志,使用GCViewer分析吞吐量和响应时间

Throughput

98.89%

Min Pause

0.00021s

Max Pause 0.01531s

Avg Pause

0.00538s

GC count

12

(3)调整最大停顿时间

比如设置最大停顿时间,获取到gc日志,使用GCViewer分析吞吐量和响应时间

Throughput

98.96%

Min Pause

0.00015s

Max Pause 0.01737s

Avg Pause

0.00574s

GC count

12

(4)启动并发GC时堆内存占用百分比

-XX:InitiatingHeapOccupancyPercent=45

G1用它来触发并发GC周期 ,基于整个堆的使用率 ,而不只是某一代内存的使用比例。值为 0 则表示“一直执行 GC循环)'. 默认值为 45 (例如 , 全部的 45% 或者使用了45%).

比如置该百分比参数,获取到gc日志,使用GCViewer分析吞吐量和响应时间

Throughput

98.11%

Min Pause

0.00406s

Max Pause 0.00532s

Avg Pause

0.00469s

GC count

12

G1调优最佳实战

官网

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc_tuning.html#r​​​​​​​ecommendations

(1)不要手动设置新生代和老年代的大小,只要设置整个堆的大

why:  https://blogs.oracle.com/poonam/increased-heap-usage-with-g1-gc

G1集器在运行过程中,会自己调整新生代和老年代的大小

其实是通过adapt代的大小来调整对象晋升的速度和年龄,从而达到为收集器设置的暂停时间果手动设置了大小就意味着放弃了G1的自动调优

(2)不断调优暂停时间目标

一般情况下这个值设置到100ms或者200ms都是可以的(不同情况下会不一样),但如果设置成50ms就不 太合理。暂停时间设置的太短,就会导致出现G1跟不上垃圾产生的速度。最终退化成Full GC。所以这个参的调优是一个持续的过程,逐步调整到最佳状态。暂停时间只是一个目标,并不能总是得到满 足。

(3)使用-XX:ConcGCThreads=n来增加标记线程的数

IHOP如果阀值置过高,可能会遇到转移失败的风险,比如对象进行转移时空间不足。如果阀值设置过 就会使标记周期运行过于频繁,并且有可能混合收集期回收不到空间。

IHOP值如果置合理,但是在并发周期时间过长时,可以尝试增加并发线程数,调高 ConcGCThreads

(4)  MixedGC调优

-XX:InitiatingHeapOccupancyPercent

-XX:G1MixedGCLiveThresholdPercent

-XX:G1MixedGCCountTarger

-XX:G1OldCSetRegionThresholdPercent

(5)适当增加堆内存大小

(6)不正常的Full GC

有时候发现系统刚刚启动的时候,就会发生一次Full GC,但是老年代空间比较充足,一般是由Metaspace 域引起的。可以通过MetaspaceSize适当增加其大家,比如256M

         

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

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

相关文章

数据库系统工程师——第五章 网络基础知识

文章目录 &#x1f4c2; 第五章、网络基础知识 &#x1f4c1; 5.1 计算机网络概述 &#x1f4d6; 5.1.1 计算机网络的概念 &#x1f4d6; 5.1.2 计算机网络的分类 &#x1f4d6; 5.1.3 网络的拓扑结构 &#x1f4c1; 5.2 网络硬件基础 &#x1f4d6; 5.2.1 网络设备 &…

Linux 文件内容相关命令使用汇总

Linux操作系统有很多强大的文件内容相关命令&#xff0c;这些命令可以让您查看、分析和编辑文件。其中&#xff0c;最基本和常用的命令包括cat、more、less和head/tail等。除了这些基本命令之外&#xff0c;grep和find命令也是文件搜索和过滤方面的有力工具。 前言 我们这篇主…

UM2080F32 低功耗32 位 Sub1GHz 无线SOC收发器芯片

产品描述 UM2080F32 是广芯微电子&#xff08;广州&#xff09;股份有限公司研制的基于 ARM Cortex M0 内核的超低功 耗、高性能的、单片集成 (G)FSK/OOK 无线收发机的 32 位 S o C 芯片。 UM2080F32 工作于 200MHz~960MHz 范围内&#xff0c;支持灵活可设的数据包格式&#xf…

危险试探,产品经理赋予AI人格来打造品牌忠诚度

图片来源&#xff1a;由无界 AI工具生成 你可能不会相信&#xff0c;你的手机很可能变成你的虚拟情人&#xff0c;升级情人需要升级手机&#xff0c;而你从此再也不想换其他品牌手机。 AI时代&#xff0c;赋予产品以人格&#xff0c;让用户爱上产品&#xff0c;这或许是接下来产…

Python整个颜色小网站,给刚刚失恋的他.........

一些过场剧情: 死党一直暗恋校花&#xff0c;但是校花对他印象也不差&#xff0c; 就是死党一直太怂了&#xff0c;不敢去找校花&#xff0c; 直到昨天看到校花登上了校董儿子的豪车&#xff0c; 死党终于彻底死心&#xff0c;大醉一场&#xff0c;作为他的兄弟&#xff0c…

井电双控智能取水计量设备-井电双控遥测终端机

井电双控遥测终端机/井电双控智能取水计量设备&#xff08;MGTR-W4122C&#xff09;是针对取水计量控制系统开发智能终端产品。集预收费、流量监测、电量监测、余额提醒、欠费停机、无线传输、远程控制等多种功能于一体&#xff0c;并可根据项目需求选择实体IC卡和APP电子卡取水…

【JavaEE】从收发消息的角度理解 TCP/IP 五层网络模型的封装与分用

文章目录 1 为什么需要分层&#xff1f;2 TCP/IP 五层网络模型3 数据的封装&#xff08;发送消息为例&#xff09;4 数据的分用&#xff08;接收消息为例&#xff09;5 实际网络环境上的封装与分用写在最后 1 为什么需要分层&#xff1f; 你问我为啥需要分层&#xff1f;那必然…

python+vue 健康体检预约管理系统

该专门体检预约管理系统包括会员和管理员。其主要功能包括个人中心、会员管理、体检服务管理、类型管理、订单信息管理、取消订单管理、 体检报告管理、通知信息管理、交流论坛、系统管理等功能。 目 录 一、绪论 1 1.1研发背景和意义 2 1.2 国内研究动态 3 1.3论文主…

US-DAT2-F、US-DAT2-A比例放大器接线

多路控制阀比例放大器接线端子定义&#xff1a; 序号 端口 名称 1 CMD1 1阀指令 2 CMD1- 1阀指令- 5 RS485_A - 6 RS485_B - 7 VREF_10V 参考电压10V 8 VREF_0V 参考电压0V 9 VAL1_A 1阀电磁铁A 10 VAL1_AB- 1阀电磁铁AB- 11 VAL1_B 1阀电磁铁B 12 PWR 电源 13 PWR…

Unreal5 实现角色动画重定向

解决问题&#xff1a; 有时候有的角色动画想用到另外的角色身上&#xff0c;不能直接用怎么办&#xff1f; 解决方案&#xff1a; 使用重定向 实现方式&#xff1a; 在资产里面创建IK绑定 在列表中选中需要绑定的骨骼网格体 需要创建两个&#xff0c;我这里是女人需要使用男…

【社区图书馆】PyTorch高级机器学习实战

PyTorch高级机器学习实战 作者&#xff1a;王宇龙&#xff0c;清华大学计算机博士&#xff0c;大型互联网公司算法专家&#xff0c;在国际学术会议及期刊发表过多篇论曾出版书籍《PyTorch深度学习入门与实战》&#xff0c;知乎"机器学习”话题优秀回答者。 亮点&#xf…

【Git 入门教程】第三节、Git的分支和合并

Git的分支和合并是Git中最重要的概念之一。使用Git可以轻松地创建、切换和合并分支&#xff0c;这为团队协作开发提供了极大的便利。在本文中&#xff0c;我们将介绍Git分支的基本概念和操作方式。 一、分支 在Git中&#xff0c;分支是指一个代码库的不同版本。分支允许开发者…

设计模式——设计模式简介、分类及面向对象设计原则

文章目录 前言一、什么是设计模式1、从面向对象谈起2、深入理解面向对象3、软件设计固有的复杂性4、软件设计复杂的根本原因——“变化”5、如何解决复杂性&#xff1f;6、软件设计的目标 二、常用设计模式及分类1、常用的七种设计模式2、设计模式分类 三、面向对象设计原则1、…

华为C++研发工程师编程题 ACM模式输入输出|| 1.汽水瓶,2.明明的随机数,3.进制转换

C ACM输入输出 1.汽水瓶题目描述思路代码如下 2.明明的随机数题目描述思路&#xff1a;代码如下&#xff1a; 3.进制转换题目描述思路&#xff1a;代码如下 题目链接&#xff1a; 华为研发工程师编程题 1.汽水瓶 题目描述 某商店规定&#xff1a;三个空汽水瓶可以换一瓶汽水…

手动泵DHP2-100、DHP-100

特性 变化的压力范围。 坚硬精密螺芯和阀套筒。 软调节。 铝制手柄和核心盘。 可以固化调节。 工业化紧凑尺寸。 可调顺序阀 DPS2-100 系列10 先导可调顺序阀 DPSK-100 系列10 先导可调顺序阀 DPSK2-100 系列10 梭阀 DSH-100 系列10 手动双向换向阀 DMP-080-2NCP 系…

vulnhub之lazysyadmin

vulnhub之lazysyadmin 一、信息收集 1.主机发现 sudo arp-scan -l发现了四台主机 192.168.158.2 00:50:56:e3:b7:e4 VMware, Inc. 192.168.158.1 00:50:56:c0:00:08 VMware, Inc. 192.168.158.248 00:0c:29:82:f1:15 VMware, Inc. 192.168.158.254 0…

PFSK164 3BSE021180R1自动调节励磁电流的方法

​ PFSK164 3BSE021180R1自动调节励磁电流的方法 在改变发电机的励磁电流中&#xff0c;一般不直接在其转子回路中进行&#xff0c;因为该回路中电流很大&#xff0c;不便于进行直接调节&#xff0c;通常采用的方法是改变励磁机的励磁电流&#xff0c;以达到调节发电机转子电流…

聚观早报|特斯拉资本支出预期至70亿-90亿美元;迪士尼再裁4000人

今日要闻&#xff1a;特斯拉资本支出预期至70亿-90亿美元&#xff1b;网易起诉暴雪要求退还3亿欠款&#xff1b;迪士尼再裁4000人&#xff1b;尼康Z8旗舰全画幅相机现身官网&#xff1b;“五一”民宿涨价毁约多平台发声 特斯拉资本支出预期至70亿-90亿美元 4 月 25 日消息&…

David Silver Reinforcement Learning -- Markov process

1 Introduction 这个章节介绍关键的理论概念。 马尔科夫过程的作用&#xff1a; 1&#xff09;马尔科夫过程描述强化学习环境的方法&#xff0c;环境是完全能观测的&#xff1b; 2&#xff09;几乎所有的RL问题可以转换成MDP的形式&#xff1b; 2 Markov Processes 2.1 Mark…

【Python】实战:生成无关联单选问卷 csv《日常生活活动评估表》

目录 一、适用场景 二、业务需求 三、Python 文件 &#xff08;1&#xff09;创建文件 &#xff08;2&#xff09;代码示例 四、csv 文件 一、适用场景 实战场景&#xff1a; 问卷全部为单选题问卷问题全部为必填问题之间无关联关系每个问题的答案分数不同根据问卷全部…