Java内存模型和常见的内存溢出类型及解决方案

news2024/11/28 6:50:10

Java内存模型与常见的内存溢出

  • 一. Java 运行过程和内存分配
    • 1 Java的平台无关性
    • 2 Java内存模型
      • 2.1Java内存模型图
    • 3 内存结构详解
      • 3.1 元空间(MetaSpace)
      • 3.2 堆区(Heap)
        • 新生代
        • 老年代
      • 3.3 虚拟机栈(VM Stack)
        • 局部变量表
        • 操作数栈
        • 动态链接
        • 返回地址
      • 3.4 本地方法栈(Native Method Stack)
      • 3.5 程序计数器(Program Counter Register)
  • 二.内存溢出类型
    • 内存溢出的类型
    • 1. 栈内存溢出(StackOverflowError)
      • 1.1 栈内存说明
      • 1.2栈溢出demo
      • 1.3栈区参数配置说明
    • 2.堆内存溢出(OutOfMemoryError:java heap space)
      • 2.1堆内存溢出
      • 2.2 堆内存溢出场景
        • 问题分析与解决
        • 1.优化项目代码
        • 2.提升Java heap size
      • 2.3 堆内存泄露
    • 3.永久代溢出(OutOfMemoryError:PermGen sapce)
    • 4.JVM参数配置
      • 配置参考
      • 堆区参数配置说明

一. Java 运行过程和内存分配

1 Java的平台无关性

JVM实现了Java语言最重要的特征:平台无关性。原理:编译后的 Java 程序指令并不直接在硬件系统的 CPU 上执行,而是由 JVM 执行。JVM屏蔽了与具体平台相关的信息,使Java语言编译程序只需要生成在JVM上运行的目标字节码(.class),就可以在多种平台上不加修改地运行。Java 虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行,因此实现java平台无关性。

在这里插入图片描述

2 Java内存模型

2.1Java内存模型图

JVM(Java Virtual Machine)是一个抽象的计算模型。它有自己的指令集和执行引擎,可以在运行时操控内存区域。目的是为构建在其上运行的应用程序提供一个运行环境。JVM可以解读指令代码并与底层进行交互:包括操作系统平台和执行指令并管理资源的硬件体系结构。
在这里插入图片描述

名称作用
元空间(Meta Area)被虚拟机加载的类信息、即时编译器编译后的代码等数据,元空间直接占用主内存(NativeMemory)
堆区(Heap)用来存储对象实例(几乎所有的对象都在这分配内存),被所有线程共享的一块内存区域,在App启动时创建,堆区的数据放在主内存
虚拟机栈区(VM Stack)存储方法的局部变量,每次开启一个线程都会创建一个虚拟机栈,线程私有,生命周期与线程相同;栈区的数据存放在高速缓存区。java方法执行的内存模型,每个方法执行的时候,都会创建一个栈帧用于保存局部变量表,操作数栈,动态链接,方法出口信息等。一个方法调用的过程就是一个栈帧从VM栈入栈到出栈的过程。
本地方法栈(Native Stack)与VM栈发挥的作用非常相似,VM栈执行java方法(字节码)服务,Native方法栈执行的是Native方法服务。
程序计数器每条线程都需要有一个程序计数器,计数器记录的是正在执行的指令地址,如果正在执行的是Native方法,这个计数器值为空(Undefined)。
执行引擎(Execution Engine)将方法区中对应方法的arm指令集加载到栈区,而栈区存在于高速缓冲区中,cpu是直接从高速缓冲区取arm指令,一条一条执行。执行引擎就像一个中介,方法对应的arm指令相当于交易的物品

3 内存结构详解

3.1 元空间(MetaSpace)

jdk1.7及其之前,方法区是堆的一个“逻辑部分”(一片连续的堆空间),但为了与堆做区分,方法区也叫“非堆”(Non-heap)或者“永久代”(PermGen sapce)
方法区是线程共享的内存区域,主要存放了被JVM加载的类信息(class字节码的信息)、常量、静态变量、即时编译后的代码等数据。方法区的数据放在主内存。
在方法区中存在一个叫运行时常量池(Runtime Constant Pool)的区域,它主要用于存放编译器生成的各种字面量和符号引用,这些内容将在类加载后存放到运行时常量池中,以便后续使用。

去方法区(永久代:PermGen)

从jdk1.8已经开始“去永久代”,方法区已经不存在。
原方法区中存储的类信息、编译后的代码数据等已经移动到了元空间(MetaSpace)中,元空间并没有处于堆内存上,而是直接占用的本地内存(NativeMemory)。把原本放在方法区中的静态变量、字符串常量池等移到堆内存中,(常量池除字符串常量池还有class常量池等,这里只是把字符串常量池移到堆内存中)

去永久代的原因

  1. 字符串存在永久代中,容易出现性能问题和内存溢出。
  2. 类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。
  3. 永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。

元空间与永久代之间最大的区别

元空间并不在虚拟机中,而是使用本地内存。因此默认情况下元空间的大小仅仅受本地内存的大小限制。类的元数据放入 native memory,
字符串池和类的静态变量放入java堆中。 这样可以加载多少类的元数据就不再由MaxPermSize控制, 而由系统的实际可用空间来控制

3.2 堆区(Heap)

堆是Java虚拟机管理的最大的一块内存,Java堆是被所有的线程共享的一块区域。在虚拟机启动时创建,其唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。
Java堆是垃圾收集器管理的主要区域,因此很多时候又被称为GC堆,Java堆可以细分为新生代和老年代

新生代

主要是用来存放新创建的对象。一般占据堆空间的1/3,由于频繁创建对象,所以新生代会频繁触发MinorGC进行垃圾回收
新生代分为Eden区、ServivorFrom、ServivorTo三个区
当JVM无法为新建对象分配内存空间的时候(Eden区满的时候),JVM触发MinorG(采用复制算法)。因此新生代空间占用越低,MinorGc越频繁

名称作用
Eden区Java新对象的出生地(如果新创建的对象占用内存很大则直接分配给老年代)。当Eden区内存不够的时候就会触发一次MinorGc,对新生代区进行一次垃圾回收
ServivorTo保留了一次MinorGc过程中的幸存者
ServivorFrom上一次GC的幸存者,作为这一次GC的被扫描者

老年代

老年代的对象比较稳定,所以MajorGC不会频繁执行。
在进行MajorGC前一般都先进行了一次MinorGC,使得有新生代的对象晋身入老年代,导致空间不够用时才触发。当无法找到足够大的连续空间分配给新创建的较大对象时也会提前触发一次MajorGC进行垃圾回收腾出空间。

MajorGC采用标记—清除算法

  1. 首先扫描一次所有老年代,标记出存活的对象
  2. 然后回收没有标记的对象。 MajorGC的耗时比较长,因为要扫描再回收。MajorGC会产生内存碎片,为了减少内存损耗,我们一般需要进行合并或者标记出来方便下次直接分配。

当老年代也满了装不下的时候,就会抛出OOM(Out of Memory)异常。

3.3 虚拟机栈(VM Stack)

  1. Java虚拟机栈是线程私有,用来存储栈帧
  2. 虚拟机栈是线程执行的区域,它保存着一个线程中方法的调用状态。
  3. 每一个被线程执行的方法,为该栈中的栈帧,即每个方法对应一个栈帧。 而栈帧持有局部变量和部分结果以及参与方法结果的调用语法,当方法调用结束以后,栈帧才会被销毁.:虚拟机栈包含了单个线程每个方法执行的栈帧,而栈帧则存储了局部变量表,关键数栈,动态链接和方法出口等信息

在这里插入图片描述

局部变量表

包含了方法执行过程中的所有变量,存放了编译期可知的各种数据类型。例如: Boolean、byte、char、short、int、float、long、double、对象引用类型(对象内存地址变量,指针或句柄)。局部变量数组所需要的空间在编译期间完成分配,在方法运行期间不会改变局部变量数组的大小。

操作数栈

操作变量的内存模型。操作数栈的最大深度在编译的时候已经确定(写入方法区code属性的max_stacks项中)。操作数栈的的元素可以是任意Java类型,包括long和double,32位数据占用栈空间为1,64位数据占用2。方法刚开始执行的时候,栈是空的,当方法执行过程中,各种字节码指令往栈中存取数据。

动态链接

每个栈帧都持有在运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态链接。

返回地址

如果有返回值的话,压入调用者栈帧中的操作数栈中,并且把PC的值指向 方法调用指令 后面的一条指令地址。

3.4 本地方法栈(Native Method Stack)

与虚拟机栈发挥的作用非常相似,VM栈执行java方法(字节码)服务,Native方法栈执行的是Native方法服务。
官方文档:

  • An implementation of the Java Virtual Machine may use conventional stacks, colloquially called “C stacks,” to support native methods (methods written in a language other than the Java programming language). Native method stacks may also be used by the implementation of an interpreter for the Java Virtual Machine’s instruction set in a language such as C. Java Virtual Machine implementations that cannot load native methods and that do not themselves rely on conventional stacks need not supply native method stacks. If supplied, native method stacks are typically allocated per thread when each thread is created.

  • This specification permits native method stacks either to be of a fixed size or to dynamically expand and contract as required by the computation. If the native method stacks are of a fixed size, the size of each native method stack may be chosen independently when that stack is created.

  • A Java Virtual Machine implementation may provide the programmer or the user control over the initial size of the native method stacks, as well as, in the case of varying-size native method stacks, control over the maximum and minimum method stack sizes.

  • The following exceptional conditions are associated with native method stacks:
    If the computation in a thread requires a larger native method stack than is permitted, the Java Virtual Machine throws a StackOverflowError.
    If native method stacks can be dynamically expanded and native method stack expansion is attempted but insufficient memory can be made available, or if insufficient memory can be made available to create the initial native method stack for a new thread, the Java Virtual Machine throws an OutOfMemoryError.

3.5 程序计数器(Program Counter Register)

  • 可以看作是当前线程所执行的字节码行号指示器(逻辑上),也就是说,程序计数器是逻辑计数器,而不是物理计数器.其工作时就是改变计数器的值来选取下一条需要执行的字节码指令,包括跳转等基础功能。由于只是记录行号,程序计数器不会发生内存泄露的问题

  • 由于JVM的多线程是通过线程的轮流切换并分配处理器执行时间的方式来实现的,在任何一个确认的时刻,一个处理器只会执行一条线程中的指令.因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程的计数器之间互不影响,独立存储,我们就称这种为线程私有的内存

  • 如果线程正在执行一个Java方法,这个计数器是记录正在执行的虚拟机字节码指令的地址,如果正在执行的native方法,那么这个计数器值就是undefined

二.内存溢出类型

内存溢出的类型

JVM提供的内存管理机制自动垃圾回收极大的解放了用户对于内存的管理,大部分情况下不会出现内存泄漏和内存溢出问题。但是出现不同的内存溢出错误可能会发生在内存模型的不同区域,所以需要根据出现错误的代码分析出现的内存溢出或内存泄漏

Java中内存溢出常见于如下的几种情形:

  • 栈内存溢出(StackOverflowError)

  • 堆内存溢出(OutOfMemoryError:java heap space)

  • 永久代溢出(OutOfMemoryError:PermGen sapce)

1. 栈内存溢出(StackOverflowError)

1.1 栈内存说明

在这里插入图片描述
栈内存可以分为虚拟机栈(VM Stack)和本地方法栈(Native Method Stack),除了它们分别用于执行Java方法(字节码)和本地方法,其余部分原理是类似的(以虚拟机栈为例说明)。Java虚拟机栈是线程私有的,当线程中方法被调度时,虚拟机会创建用于保存局部变量表、操作数栈、动态连接和方法出口等信息的栈帧(Stack Frame)

当线程执行某个方法时,JVM会创建栈帧并压栈,此时刚压栈的栈帧就成为了当前栈帧。如果该方法进行递归调用时,JVM每次都会将保存了当前方法数据的栈帧压栈,每次栈帧中的数据都是对当前方法数据的一份拷贝。如果递归的次数足够多,多到VM栈中栈帧所使用的内存超出了栈内存的最大容量,此时JVM就会抛出StackOverflowError

1.2栈溢出demo

StackOverflowErrorDemo.java

package com.cxstar.demo;

/**
 * @author zhouquan
 * @description 栈溢出测试
 * @date 2023年6月4日10:27:20
 **/
public class StackOverflowErrorDemo {

    private static int stackLength = 0;

    public void pusStack() {
        stackLength++;
        pusStack();
    }

    public static void main(String[] args) {
        StackOverflowErrorDemo demo = new StackOverflowErrorDemo();
        try {
            demo.pusStack();
        } catch (Throwable e) {
            System.out.println("stack length: " + demo.stackLength);
            throw e;
        }
    }

}

执行结果:

stack length: 19625
Exception in thread "main" java.lang.StackOverflowError
	at com.cxstar.demo.StackOverflowErrorDemo.pusStack(StackOverflowErrorDemo.java:23)
	at com.cxstar.demo.StackOverflowErrorDemo.pusStack(StackOverflowErrorDemo.java:23)
	at com.cxstar.demo.StackOverflowErrorDemo.pusStack(StackOverflowErrorDemo.java:23)
	at com.cxstar.demo.StackOverflowErrorDemo.pusStack(StackOverflowErrorDemo.java:23)
	at com.cxstar.demo.StackOverflowErrorDemo.pusStack(StackOverflowErrorDemo.java:23)
	at com.cxstar.demo.StackOverflowErrorDemo.pusStack(StackOverflowErrorDemo.java:23)

1.3栈区参数配置说明

官方文档可以看到: 对于Windows操作系统, 其默认值取决于虚拟内存的大小.
对于Linux系统或者OS X 系统, 默认值是1024KB

参数名含义
-Xss设置单个线程栈的大小, 一般默认为512K~1024K,其等价于 -XX:ThreadStackSize

2.堆内存溢出(OutOfMemoryError:java heap space)

堆内存的唯一作用就是存放数组和对象实例,即通过new指令创建的对象,包括数组和引用类型

2.1堆内存溢出

当堆中对象实例所占的内存空间超出了堆内存的最大容量,JVM就会抛出OutOfMemoryError:java heap space异常
如果是因为堆内存空间太小,可以通过改变-Xmx来进行调整,或者分析程序中对象的生命周期和存储结构等信息进行调整;

2.2 堆内存溢出场景

最近客户反馈在生产环境导入操作时遇到任务一直执行中,(导入时需要对pdf进行封面提取和pdf加密,且pdf最大可能会超过500MB)并且入库的数据量一直不改变。通过日志查询,终于定位到报错信息如下:

java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Unknown Source) ~[na:1.8.0_221]
	at java.io.ByteArrayOutputStream.grow(Unknown Source) ~[na:1.8.0_221]
	at java.io.ByteArrayOutputStream.ensureCapacity(Unknown Source) ~[na:1.8.0_221]
	at java.io.ByteArrayOutputStream.write(Unknown Source) ~[na:1.8.0_221]
	at com.cxstar.common.utils.DESUtil.decryptFile(DESUtil.java:193) ~[cxstar-common-1.0.0.jar!/:1.0.0]
	at com.cxstar.business.service.impl.ArchiveServiceImpl.upload(ArchiveServiceImpl.java:103) ~[cxstar-business-1.0.0.jar!/:1.0.0]
	at com.cxstar.business.factory.AsyncFactory.importAttachment(AsyncFactory.java:1016) ~[cxstar-business-1.0.0.jar!/:1.0.0]
	at com.cxstar.business.factory.AsyncFactory.access$800(AsyncFactory.java:62) ~[cxstar-business-1.0.0.jar!/:1.0.0]
	at com.cxstar.business.factory.AsyncFactory$7.run(AsyncFactory.java:708) ~[cxstar-business-1.0.0.jar!/:1.0.0]
	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[na:1.8.0_221]
	at java.util.concurrent.FutureTask.run(Unknown Source) ~[na:1.8.0_221]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source) ~[na:1.8.0_221]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) ~[na:1.8.0_221]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_221]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_221]
	at java.lang.Thread.run(Unknown Source) [na:1.8.0_221]

问题分析与解决

java.lang.OutOfMemoryError: Java heap space (JVM 堆空间溢出)简单来说就是在创建新的对象时, 堆内存中的空间不足以存放新创建的对象,导致此种问题的发生。

1.优化项目代码

根据报错信息定位到内存消耗较大的代码,然后对其进行重构或者优化算法。如果是在生产环境,务必要在内存消耗过大的代码出增加日志信息输出,否则容易像我定位一晚上才找到问题所在
在这里插入图片描述

2.提升Java heap size

增加堆内存空间设置

-server -Xms4096m -Xmx4096m -XX:PermSize=256M -XX:MaxNewSize=512m -XX:MaxPermSize=512m

客户生产环境的服务器是8g内存,并且操作系统是比较老的windows server 2008服务器。在部署项目时使用winsw工具将jar包安装为服务。因此在项目启动时,增加内存参数,修改后配置如下:

<service>
    <id>app-id</id>
    <name>app-name service</name>
    <description>application descriptions</description>

	<!-- 配置的启动:使用jar -jar方式运行项目 -->
    <executable>java</executable>
    <arguments>-jar -server -Xms4096m -Xmx4096m -XX:PermSize=256M -XX:MaxNewSize=512m -XX:MaxPermSize=512m  "D:\application\api-rest-1.0.0.jar"</arguments>

    <startmode>Automatic</startmode>
    <logpath>%BASE%\logs</logpath>
    <logmode>rotate</logmode>
</service>

2.3 堆内存泄露

当堆中一些对象不再被引用但垃圾回收器无法识别时,这些未使用的对象就会在堆内存空间中无限期存在,不断的堆积就会造成内存泄漏。
如果发生了内存泄漏,则可以先找出导致泄漏发生的对象是如何被GC ROOT引用起来的,然后通过分析引用链找到发生泄漏的地方。

3.永久代溢出(OutOfMemoryError:PermGen sapce)

我们知道Hotspot jvm通过永久带实现了Java虚拟机规范中的方法区,而运行时的常量池就是保存在方法区中的,因此永久带溢出有可能是运行时常量池溢出,也有可能是方法区中保存的class对象没有被及时回收掉或者class信息占用的内存超过了我们配置

当持久带溢出的场景下出现

  1. 使用一些应用服务器的热部署的时候,我们就会遇到热部署几次以后发现内存溢出了,这种情况就是因为每次热部署的后,原来的class没有被卸载掉。
  2. 如果应用程序本身比较大,涉及的类库比较多,但是我们分配给持久带的内存(通过-XX:PermSize和-XX:MaxPermSize来设置)比较小的时候也可能出现此种问题。
  3. 一些第三方框架,比如spring,hibernate都通过字节码生成技术(比如CGLib)来实现一些增强的功能,这种情况可能需要更大的方法区来存储动态生成的Class文件。

4.JVM参数配置

配置参考

  • 服务器内存8G ,所以可以采取以下配置: set JAVA_OPTS=-server -Xms4096m -Xmx4096m
    -XX:PermSize=256M -XX:MaxNewSize=512m -XX:MaxPermSize=512m

  • 服务器内存4G ,所以可以采取以下配置: set JAVA_OPTS=-server -Xms2048m -Xmx2048m
    -XX:PermSize=256M -XX:MaxNewSize=512m -XX:MaxPermSize=512m

  • 服务器内存2G ,所以可以采取以下配置: set JAVA_OPTS=-server -Xms1024m -Xmx1024m
    -XX:PermSize=256M -XX:MaxNewSize=512m -XX:MaxPermSize=512m

  • 服务器内存1G ,所以可以采取以下配置: set JAVA_OPTS=-server -Xms512m -Xmx512m -XX:PermSize=128M
    -XX:MaxPermSize=256M -XX:MaxPermSize=256m

  • 服务器内存512M ,所以可以采取以下配置: set JAVA_OPTS=-server -Xms256m -Xmx256m
    -XX:PermSize=256M -XX:MaxNewSize=128m -XX:MaxPermSize=128m

堆区参数配置说明

堆区:通常会将-Xms 与-Xmx两个参数的配置相同的值,其目的是为了能够在java垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小而浪费资源

参数名含义
-Xmsjava虚拟机初始化时的最小内存
-Xmxjava虚拟机可使用的最大内存

非堆区:代码、常量、外部访问(比如流在传输数据时所占用的资源)等,java垃圾回收机制只作用于堆区,非堆区不会被java垃圾回收机制进行处理

参数名含义
-XX:newSize表示对象创建初始内存的大小,应小于-Xms的值
-XX:MaxnewSize表示对象创建可被分配的内存的最大上限,应小于-Xmx的值
-Xmnjdk1.4后对-XX:newSize、-XX:MaxnewSize两个参数同时进行配置

永久代:在配置之前一定要慎重的考虑一下自身软件所需要的非堆区内存大小,因为此处内存是不会被java垃圾回收机制进行处理的地方。并且更加要注意的是最大堆内存与最大非堆内存的和绝对不能够超出操作系统的可用内存。

参数名含义
-XX:PermSize表示非堆区初始内存分配大小(方法区)
-XX:MaxPermSize表示对非堆区分配的内存的最大上限(方法区)

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

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

相关文章

Linux :: vim 编辑器:详解:光标移动定位内容,行间:快速定位至文本:开头 / 结尾;行内:词间跳跃

前言&#xff1a;本篇是 Linux 基本操作篇章的内容&#xff01; 笔者使用的环境是基于腾讯云服务器&#xff1a;CentOS 7.6 64bit。 学习集&#xff1a; C 入门到入土&#xff01;&#xff01;&#xff01;学习合集Linux 从命令到网络再到内核&#xff01;学习合集 前言&#x…

Asana替代方案推荐:盘点2023年8种优质的免费和付费替代工具

Asana是一个项目管理和团队合作软件平台&#xff0c;自2008年成立以来&#xff0c;一直在彻底改变团队合作的方式。Asana以其直观的用户界面而闻名&#xff0c;是项目经理和团队领导的热门选择。然而在快节奏的项目管理世界中&#xff0c;技术发展很快。因此&#xff0c;当涉及…

chatgpt赋能python:Python取余方法介绍

Python取余方法介绍 在Python编程中&#xff0c;取余&#xff08;也称为求模运算或取模运算&#xff09;是计算机程序经常使用的一种基本算术运算。Python提供了两种方法来执行取余运算&#xff1a;使用百分号符号&#xff08;%&#xff09;和divmod()函数。 使用百分号符号&…

揭秘HTTP代理的神奇力量:让你的系统突破内网限制

大家好&#xff0c;我是你们的小米&#xff01;今天&#xff0c;我要和大家聊聊一个技术问题&#xff0c;那就是关于"http代理"的使用。昨日&#xff0c;我刚刚午休睡醒&#xff0c;项目经理杰哥叫我关注下其中一个项目的部署进展情况。而就在这时&#xff0c;客户侧…

15天学会EasyX 第2天:EasyX里的设备坐标与打开关闭绘图窗口

本文为山城瑞宝创作&#xff0c;转载请标注版权&#xff01; 本文里的函数使用都不需要先写明原型&#xff0c;原型就在其对应的库里&#xff08;直接用&#xff09; 目录 1. 设备及其坐标 2. 如何打开与关闭绘图窗口 2.1. initgraph 2.1.1. 没有flag的代码示例 2.1.2. 使用了…

会声会影2023旗舰中文试用版下载安装教程

会声会影2023版(Corel VideoStudio)是一款专业视频制作软件及视频剪辑软件,可以剪辑合并视频,制作视频,屏幕录制,光盘制作,视频后期编辑,添加特效,字幕和配音等操作,界面美观,素材丰富,操作简洁而! 会声会影有多轨道式编辑功能&#xff0c;可以独立处理视频、图片、音频等素材&…

MATLAB笔记总结(1) 东华大学MOOC

循环语句 MATLAB函数句柄 https://zhuanlan.zhihu.com/p/266263265 https://blog.csdn.net/shaozheng0503/article/details/130305984?spm1001.2014.3001.5501 数据和变量 表达式 分号;) 逗号(, ), 省略号(3个英文句点…)。 历史指令调用&#xff1a;用方向键(↑↓) 数据…

离散分类和非离散分类问题中的模型评价

离散分类问题中的模型评价 假设分类目标只有两类&#xff1a;正样本&#xff08;positive&#xff09;和负样本&#xff08;negative&#xff09;。 分类器的分类结果会出现以下四种情况&#xff1a; TP: 若一个实例为正&#xff0c;且被预测为正&#xff0c;即为“真正类”(…

chatgpt赋能python:Python去空格输出:优化您的代码和网站速度

Python去空格输出&#xff1a;优化您的代码和网站速度 Python是一种简单易用的编程语言&#xff0c;广泛用于各种应用和网站开发。然而&#xff0c;Python的代码输出&#xff08;如HTML和CSS&#xff09;中不可避免地包含了空格、制表符和换行符。这些额外的字符可能会影响网站…

模式识别算法的常见评价指标TP/FP/FN/TN,ROC,DET,EER

文章目录 TP/FP/FN/TN&#xff08;TA/FA/FR/TR&#xff09;误报率&#xff08;FAR&#xff09;漏报率&#xff08;FRR&#xff09; ROC曲线&#xff08;Receiver Operating Characteristic Curve&#xff0c;受试者特征曲线&#xff09;DET曲线&#xff08;Detection Error Tra…

Maven高级——继承与聚合——版本锁定

在前面的文章已经实现了Maven的继承&#xff0c;初次之外&#xff0c;还可以在父工程当中统一管理依赖的版本。 场景介绍 有一些依赖不是各个模块共有的&#xff0c;则需要到那些子模块当中单独配置了&#xff0c;这时需要到各个模块单独配置了&#xff0c;比如下图有一个模块…

【小沐学Python】Python实现Web服务器(CentOS+Docker下部署Flask)

&#x1f37a;基于Python的Web服务器系列相关文章编写如下&#x1f37a;&#xff1a; &#x1f388;【Web开发】Python实现Web服务器&#xff08;Flask快速入门&#xff09;&#x1f388;&#x1f388;【Web开发】Python实现Web服务器&#xff08;Flask案例测试&#xff09;&a…

Pyside6-第五篇-单选按钮QRadioButton

今天是Pyside6的第五篇内容。一起来看单选按钮。 QRadioButton。 class QRadioButton(QAbstractButton):"""QRadioButton(self, parent: Optional[PySide6.QtWidgets.QWidget] None) -> NoneQRadioButton(self, text: str, parent: Optional[PySide6.QtWidg…

9.wxss

wxss基本满足所有css&#xff0c;并在css的基础上增加了 rpx 尺寸单位import 导入样式 目录 1 rpx 2 import 3 全局样式与局部样式 4 样式权重 1 rpx rpx(responsive pixel)&#xff0c;中文名叫响应像素&#xff0c;它是用来解决屏幕适配的尺寸单位&#xff0c;它…

Flink第九章:Flink CEP

系列文章目录 Flink第一章:环境搭建 Flink第二章:基本操作. Flink第三章:基本操作(二) Flink第四章:水位线和窗口 Flink第五章:处理函数 Flink第六章:多流操作 Flink第七章:状态编程 Flink第八章:FlinkSQL Flink第九章:Flink CEP 文章目录 系列文章目录前言一、简单案例1.Logi…

Linux高性能服务器编程|阅读笔记:第11章 - 定时器

目录 简介系列笔记11.1 socket选项SO_RCVTIMEO和SO_SNDTIMEO11.2 SIGALRM信号11.2.1 基于升序链表的定时器11.2.2 处理非活动连接11.3 I/O复用系统调用的超时参数11.4 高性能定时器11.4.1 时间轮11.4.2 时间堆结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方…

光储存技术及原理

描述 信息资料迅速增长是当今社会的一大特点。有人统计&#xff0c;科技文献数量大约每7年增加1倍&#xff0c;而一般的情报资料则以每2年~3年翻一番的速度增加。大量资料的存储、分析、检索和传播&#xff0c;迫切需要高密度、大容量的存储介质和管理系统。 1898年荷兰的Vald…

Jenkins+Docker 实现一键自动化部署项目!步骤齐全,少走坑路

本文章实现最简单全面的Jenkinsdockerspringboot 一键自动部署项目&#xff0c;步骤齐全&#xff0c;少走坑路。 环境&#xff1a;centos7git(gitee) 简述实现步骤&#xff1a;在docker安装jenkins&#xff0c;配置jenkins基本信息&#xff0c;利用Dockerfile和shell脚本实现…

javaScript蓝桥杯-----芝麻开门

目录 一、介绍二、准备三、目标四、代码五、完成 一、介绍 在阿里巴巴和四十大盗的故事中&#xff0c;阿里巴巴因为无意中知道了开门的咒语人生发生了翻天覆地的变化&#xff0c;四十大盗也因为咒语的泄露最终丧命。芝麻开门的咒语作为重要的信息推动着故事的发展。下面由你来…

初识网络之TCP网络套接字

目录 一、TCP常用网络接口 1. 监听服务器 2. 接收链接 3. 发起连接 二、实现一个简单的tcp程序 1. 日志函数 2. 服务端文件 2.1 .hpp文件 2.2 .cpp文件 3. 客户端文件 3.1 .hpp文件 3.2 .cpp文件 4. 程序测试 三、实现支持多个用户并发访问的tcp程序 1. 当前程序…