java--jvm虚拟机(都是要点)

news2024/11/18 21:48:13

请带着以下问题,学习并理解jvm


问题一: 为什么fullGC会对系统性能有影响?youngGC却几乎没有?

问题二: outofmemory是什么异常?什么时候会出现?如何处理?

问题三: 线程安全和不安全在jvm内存模型中是如何表现的?

问题四: 提升fullGC回收的速度的方法有哪些?

问题五: 为什么频繁fullGC常伴随CPU的满负荷

一,简介

Java Virtual Machine(JVM,Java 虚拟机)是 Java 平台的核心组件之一,
负责执行 Java 字节码并为 Java 程序提供运行时环境。JVM 使得 Java 程序具有“编写一次,随处运行”的能力,
允许 Java 程序在不同的平台上执行,而不需要重新编译。

1,主要组成部分

  • 类加载器子系统 (Class Loader Subsystem)

    • 负责将 .class 文件加载到内存中。
  • 运行时数据区 (Runtime Data Areas)

    • 方法区 (Method Area):存储类信息、常量、静态变量和方法代码。
    • 堆 (Heap):存储所有对象实例和数组。
    • 栈 (Java Stack):存储每个线程的局部变量和部分结果。每调用一个方法都会创建一个新的栈帧。
    • 程序计数器 (Program Counter Register):保存当前线程执行的字节码指令的地址。
    • 本地方法栈 (Native Method Stack):为每个线程保存本地方法的信息。
  • 执行引擎 (Execution Engine)

    • 解释器 (Interpreter):逐条解释执行字节码指令。
    • 即时编译器 (JIT Compiler):将热点代码编译为机器码以提高性能。
    • 垃圾收集器 (Garbage Collector):自动管理内存,回收不再使用的对象。

二,jvm工作原理

  • 启动:启动类加载器将启动类(包含 main 方法的类)加载到 JVM 中。
  • 类加载:类加载器根据需要动态加载其他类。
  • 字节码验证:验证加载的字节码以确保其安全性和正确性。
  • 解释/编译执行:执行引擎解释或编译字节码,然后执行相应的机器码。
  • 垃圾收集:垃圾收集器在后台运行,自动回收不再使用的内存。

三,内存模型

程序计数器(Program Counter Register)
虚拟机栈(JVM Stack)
本地方法栈(Native Method Stack)
堆(Heap)
方法区(Method Area)
运行时常量池(Runtime Constant Pool)
直接内存(Direct Memory)

程序计数器(Program Counter Register)
功能:程序计数器是一个较小的内存区域,用于记录当前线程所执行的字节码的地址。它是线程私有的,每个线程都有一个独立的程序计数器。
作用:在多线程环境中,程序计数器用于保持线程的执行状态,帮助线程在执行方法调用和返回时能够正确地恢复执行位置。

虚拟机栈(JVM Stack)
功能:虚拟机栈用于存储方法调用、局部变量、操作数栈、动态链接和方法出口等信息。每个线程都有一个独立的虚拟机栈。
结构:
栈帧(Stack Frame):每个方法调用对应一个栈帧,栈帧包含局部变量表、操作数栈、动态链接和方法返回地址等。
局部变量表(Local Variable Table):存储方法的参数和局部变量。
操作数栈(Operand Stack):执行方法时,操作数栈用于存放中间计算结果。

本地方法栈(Native Method Stack)
功能:本地方法栈与虚拟机栈类似,但是它用于支持 Native 方法的调用。Native 方法是用其他语言(如 C/C++)编写的方法,通过 JNI(Java Native Interface)与 Java 代码交互。
区别:本地方法栈用于支持本地代码的执行,而虚拟机栈主要用于 Java 字节码的执行。

堆(Heap)
功能:堆是 JVM 中最大的内存区域,用于存储所有的对象实例和数组。它是垃圾回收器(GC)主要关注的区域。
结构:
新生代(Young Generation):用于存储新创建的对象。新生代又分为 Eden 区和两个 Survivor 区(S0 和 S1)。对象在新生代经过若干次 GC 后,如果仍然存活,会被晋升到老年代。
老年代(Old Generation):用于存储长时间存活的对象。老年代的 GC 比较少,通常是 Full GC 或 Major GC。
永久代(PermGen)(Java 8 之前):存储类的元数据、静态变量等。Java 8 及之后版本中被方法区替代。
元空间(Metaspace)(Java 8 及之后):替代永久代,存储类的元数据,不再使用堆内存,而是使用本地内存。

方法区(Method Area)
功能:方法区是 JVM 的一部分,用于存储已加载的类信息、常量池、静态变量和即时编译器编译后的代码等。
区别:方法区是 JVM 堆的一部分,但它专门用于存储类相关的数据,与堆中对象的数据分开管理。

运行时常量池(Runtime Constant Pool)
功能:运行时常量池是方法区的一部分,用于存储类文件中的常量(如字符串字面量、类和方法的引用)。
结构:在类加载时,常量池中的常量会被加载到方法区的运行时常量池中。

直接内存(Direct Memory)
功能:直接内存是 JVM 堆外的内存区域,通过 java.nio 包的 ByteBuffer 类进行访问。直接内存用于提高 I/O 操作的效率。
特点:直接内存的分配和释放不受 JVM 垃圾回收的直接管理,但它需要通过 Unsafe 类或 JNI 进行操作。

四,垃圾回收

垃圾回收(Garbage Collection, GC)是 Java 虚拟机(JVM)内存管理中的一个重要方面,它负责自动回收不再使用的对象,以释放内存空间。垃圾回收算法的选择和实现直接影响到应用程序的性能、
响应时间和资源使用效率。以下是一些常见的垃圾回收算法和策略的介绍:

1. 垃圾回收算法概述

垃圾回收算法可以大致分为以下几种类型:

引用计数(Reference Counting)
标记-清除(Mark-Sweep)
标记-整理(Mark-Compact)
复制算法(Copying)
分代收集(Generational Collection)

2. 引用计数(Reference Counting)

原理:

  • 每个对象维护一个计数器,记录对它的引用数量。当引用计数变为零时,表示对象不再被使用,可以被回收。

优点:

  • 实现简单,回收实时性高。

缺点:

  • 无法处理循环引用(即两个或多个对象互相引用),导致内存泄漏。
  • 需要额外的内存开销来维护引用计数。

3. 标记-清除(Mark-Sweep)

原理:

  • 标记阶段:从根对象(如栈中的引用)开始,遍历所有可达的对象,并标记这些对象。
  • 清除阶段:遍历堆中的所有对象,回收那些没有被标记的对象。

优点:

  • 实现简单,能有效地回收不再使用的对象。

缺点:

  • 碎片化:标记和清除的过程中可能产生内存碎片。
  • 性能开销:清除阶段可能会对堆内存进行大量扫描和清理,影响性能。

4. 标记-整理(Mark-Compact)

原理:

  • 标记阶段:与标记-清除算法相同,标记所有可达的对象。
  • 整理阶段:将所有被标记的对象移动到堆的一端,清理空闲的内存区域。

优点:

  • 无碎片化:整理阶段将对象紧凑地移动到堆的一端,避免了内存碎片问题。

缺点:

  • 性能开销:需要移动对象,可能导致额外的开销。

5. 复制算法(Copying)

原理:

  • 将堆分为两个相等的区域(如 Survivor 区和 Eden 区)。在回收时,将活动对象从一个区域复制到另一个区域。
  • 完成后,清空原来的区域,交换两个区域的角色。

优点:

  • 简化管理:只需要处理两个区域中的对象,避免了内存碎片化。
  • 高效:对于新生代对象,复制算法可以高效地回收。

缺点:

  • 内存开销:需要额外的内存来维护两个区域。
  • 对象移动:需要将对象从一个区域复制到另一个区域,可能会导致性能开销。

6. 分代收集(Generational Collection)

原理:
        根据对象的生命周期将堆划分为不同的区域(新生代和老年代)。
        新生代:用于存放新创建的对象,通常使用复制算法。
        老年代:用于存放经过多次 GC 仍然存活的对象,通常使用标记-整理算法。
        长期存活对象:会从新生代晋升到老年代。
优点:

  •         优化:新生代通常包含大量短生命周期的对象,使用复制算法可以高效地处理这些对象。老年代则处理长期存活的对象,减少了 GC 的频率。
  •         灵活:可以根据对象的生命周期优化垃圾回收策略。

缺点:
        复杂性:需要管理多个区域和不同的垃圾回收算法。

7. 常见的垃圾回收器

Java 的垃圾回收器基于以上算法设计,并提供了不同的 GC 策略和实现:

Serial GC:

使用标记-清除和标记-整理算法,适合单核处理器。
-XX:+UseSerialGC

Parallel GC(吞吐量优先 GC):

适合多核处理器,使用多线程并行处理新生代和老年代的垃圾回收。
-XX:+UseParallelGC

Concurrent Mark-Sweep (CMS) GC(低延迟 GC):

主要使用标记-清除算法,降低了垃圾回收的暂停时间。
-XX:+UseConcMarkSweepGC

G1 GC(Garbage First GC):

旨在实现低延迟和高吞吐量,通过将堆划分为多个区域(Region)来优化 GC。
-XX:+UseG1GC

ZGC(Z Garbage Collector):

旨在提供低延迟的垃圾回收,支持大内存(TB级别)。
-XX:+UseZGC

Shenandoah GC:

提供低延迟和可预测的 GC 暂停时间,适用于大内存应用。
-XX:+UseShenandoahGC

JDK 1.8 的默认垃圾回收算法
默认垃圾回收器
        Parallel GC(也称为 Throughput Collector)
特点

  • 新生代:Parallel GC 在新生代使用 复制算法(Copying Algorithm),将对象从 Eden 区复制到 Survivor 区(S0 和 S1)。当一个 Survivor 区满时,存活的对象会被复制到另一个 Survivor 区或老年代。
  • 老年代:在老年代使用 标记-整理算法(Mark-Compact),对象会被整理到堆的一端,回收未被引用的对象,并且解决内存碎片问题。

JDK 11 的默认垃圾回收算法
默认垃圾回收器
        G1 GC(Garbage-First Garbage Collector)
特点

  • 新生代:G1 GC 也会使用类似复制算法的机制,在新生代中对对象进行管理。
  • 老年代:G1 GC 使用 分代收集 和 区域划分,将堆分为多个小块(Region)。G1 GC 在回收时会优先回收垃圾最多的区域,并进行 并行 和 并发 的垃圾回收。
  • 性能:G1 GC 旨在提供低延迟和高吞吐量,适合处理大内存和高负载的应用。

默认配置

  • 新生代和老年代的区域划分:G1 GC 将堆划分为多个大小相同的区域(Region),新生代和老年代都使用这些区域。
  • 垃圾回收参数:默认使用 -XX:+UseG1GC。可以通过 -XX:MaxGCPauseMillis 设置期望的最大 GC 暂停时间。

JDK 17 的默认垃圾回收算法
默认垃圾回收器
        G1 GC(Garbage-First Garbage Collector)
特点

  • 新生代:G1 GC 在新生代中使用与 JDK 11 相似的复制算法。
  • 老年代:G1 GC 在老年代中使用标记-整理和分代收集策略。G1 GC 在 JDK 17 中继续优化性能,改进了 并发标记 和 并发整理 机制。
  • 性能:G1 GC 仍然提供低延迟的 GC 机制,同时更好地支持大内存应用。

默认配置

  • 新生代和老年代的区域划分:堆依然被划分为多个 Region。G1 GC 的区域划分和垃圾回收策略在 JDK 17 中继续优化。
  • 垃圾回收参数:默认使用 -XX:+UseG1GC。G1 GC 在 JDK 17 中进一步优化了 GC 暂停时间和吞吐量,可以通过 -XX:MaxGCPauseMillis 和 -XX:InitiatingHeapOccupancyPercent 等参数来调整。

总结
JDK 1.8 默认使用 Parallel GC,主要通过标记-清除和标记-整理算法进行垃圾回收,适合于吞吐量优先的场景。
JDK 11 和 JDK 17 默认使用 G1 GC,它是一个低延迟的垃圾回收器,适合处理大内存和要求较低 GC 暂停时间的应用。G1 GC 通过将堆划分为多个区域,并优先回收垃圾最多的区域,来提供高效的垃圾回收服务。

五,youngGC与fullGC

Young GC(新生代垃圾回收)

概述
Young GC 是指对 新生代(Young Generation) 内存区域的垃圾回收。新生代主要用于存储新创建的对象,这些对象在生命周期的早期通常具有较短的存活时间。Young GC 是对这些对象的回收操作,目的是清理掉短生命周期的对象,腾出空间给新的对象。

新生代的组成
Eden 区:新创建的对象首先被分配到 Eden 区。
Survivor 区:Eden 区中存活的对象会被移动到 Survivor 区,通常有两个 Survivor 区,S0 和 S1。

Young GC 的过程

对象分配:新创建的对象首先分配到 Eden 区。
Minor GC:当 Eden 区满时,会触发 Young GC(也称为 Minor GC)。在 Young GC 过程中,垃圾回收器会标记和清除 Eden 区中不再被引用的对象。
对象晋升:存活的对象会被移动到 Survivor 区。如果对象在 Survivor 区经过一定次数的 GC 仍然存活,就会被晋升到老年代。
GC 频率:由于新生代的空间通常较小,Young GC 的频率较高。它旨在快速回收短生命周期的对象,以减少对老年代的压力。

Young GC 的特点

回收速度快:由于新生代中的对象大多是短生命周期的,回收过程通常很快。
暂停时间较短:Young GC 通常是应用程序的暂停时间较短的 GC 操作,但它会频繁发生。
主要回收新创建的对象:清理短生命周期对象,避免它们占用老年代的空间。

Full GC(完全垃圾回收)

概述
Full GC 是指对 整个堆内存(包括新生代和老年代) 进行垃圾回收的操作。Full GC 包括对新生代和老年代的回收,它通常发生在以下几种情况下:

老年代内存不足:当老年代内存不足时,触发 Full GC 来回收老年代中的垃圾对象。
永久代或元空间内存不足:在 Java 8 之前,永久代(PermGen)用于存储类的元数据,内存不足时也会触发 Full GC。Java 8 及之后版本中的元空间(Metaspace)类似地可能导致 Full GC。
手动触发:使用 System.gc() 方法手动触发 Full GC,虽然不推荐在生产环境中使用。

Full GC 的过程

标记-清除:与新生代的 Young GC 类似,Full GC 也使用标记-清除或标记-整理算法来清理无用对象。
标记-整理:在老年代中,Full GC 可能会使用标记-整理算法,将存活的对象移动到堆的一端,回收未被引用的对象,解决内存碎片问题。
类加载器的回收:在 Full GC 中,还可能会回收不再使用的类及其元数据。
Full GC 的特点
回收范围广:Full GC 涉及整个堆的回收,包括新生代和老年代。
暂停时间较长:由于回收范围广,Full GC 通常会导致较长时间的应用暂停。
频率较低:相比 Young GC,Full GC 的发生频率较低,但每次发生时的停顿时间较长。


Young GC 和 Full GC 的对比

特性  Young GC Full GC
回收范围 仅回收新生代(Young Generation) 回收整个堆(包括新生代和老年代)
触发条件新生代内存不足,通常在 Eden 区满时触发老年代内存不足,永久代或元空间内存不足
停顿时间 较短,频繁发生较长,较少发生
对应用的影响 相对较小,但可能会影响吞吐量和响应时间较大,可能会导致显著的应用暂停
回收策略 复制算法(Eden 区到 Survivor 区)标记-清除、标记-整理等复杂算法

六,jvm异常

当 JVM 堆内存不够用时,通常会出现以下几种异常或错误:

1. OutOfMemoryError

OutOfMemoryError 是 JVM 在运行时抛出的错误,表示 JVM 已经耗尽了可用的堆内存。这个错误有几个不同的具体类型,分别针对不同的内存不足情况:

java.lang.OutOfMemoryError: Java heap space

说明:这是最常见的堆内存不足错误,表示 Java 堆(Heap)内存空间不足,无法分配足够的内存来创建新的对象。
触发条件:通常发生在堆内存设置不够、内存泄漏、或应用程序创建了大量对象但未能及时释放它们时。

java.lang.OutOfMemoryError: GC overhead limit exceeded

说明:这是指 JVM 在进行垃圾回收时,尽管进行了频繁的 GC,但回收的内存仍然远远不足以满足应用程序的需求。这个错误通常表明应用程序存在内存泄漏或配置不合理的问题。
触发条件:当 GC 占用的 CPU 时间过多,且回收的内存总量占用总内存的比例过低时,会触发此错误。这个错误可以通过设置 -XX:-UseGCOverheadLimit 来关闭 GC 开销限制检测。

java.lang.OutOfMemoryError: Requested array size exceeds VM limit

说明:当应用程序试图创建一个大小超过 JVM 允许的最大数组时,抛出此错误。
触发条件:试图分配的数组太大,超出了 JVM 对数组大小的限制。

2. 内存不足的常见原因

堆内存设置不足:JVM 的堆内存设置过低,无法满足应用程序的需求。可以通过 -Xmx 参数增加最大堆内存大小,例如 -Xmx2g 设置最大堆内存为 2GB。

内存泄漏:应用程序中存在内存泄漏,导致对象无法被回收,从而不断消耗堆内存。

大对象分配:试图分配一个过大的对象或数组,超出了堆内存的限制。

垃圾回收不足:GC 策略不适合应用场景,导致内存回收不及时,增加了堆内存压力。

3. 如何诊断和解决

监控和分析:

使用 JVM 提供的工具(如 jstat, jmap, jconsole)和外部工具(如 VisualVM, GCViewer)来监控堆内存使用情况,分析 GC 日志,识别内存使用模式和可能的内存泄漏。

调整 JVM 参数:

增加堆内存大小:通过 -Xms 和 -Xmx 调整堆的初始和最大大小。例如,-Xmx4g 设置最大堆内存为 4GB。
调整 GC 策略:选择合适的垃圾回收器和调整其参数。例如,使用 -XX:+UseG1GC 启用 G1 垃圾回收器并调整相关参数。

代码优化:

检查和修复内存泄漏:使用内存分析工具查找并修复内存泄漏,例如通过 Heap Dump 分析,找到持有大量对象引用的地方。
优化对象创建和生命周期管理:避免过度创建和缓存对象,合理管理对象的生命周期。

配置优化:

配置适当的 -XX:MaxGCPauseMillis 来调整 GC 暂停时间,以平衡 GC 停顿时间和吞吐量。
配置适当的 -XX:NewRatio、-XX:SurvivorRatio 等参数来优化新生代和老年代的内存分配。

4. 示例配置

# 增加最大堆内存到 4GB
java -Xmx4g -Xms4g -jar myapp.jar

# 启用 G1 GC 并设置最大 GC 暂停时间为 200ms
java -Xmx4g -Xms4g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar myapp.jar

# 禁用 GC 开销限制检测
java -Xmx4g -Xms4g -XX:-UseGCOverheadLimit -jar myapp.jar

七,jvm的线程独享区与共享区

上面已经介绍了jvm的内存模型,我们再将其按照线程独享与共享进行划分

线程独享:

程序计数器(Program Counter Register)

作用:每个线程有一个独立的程序计数器,记录当前线程正在执行的字节码的行号。
特性:它是线程私有的,线程切换不会影响其他线程的程序计数器状态。

虚拟机栈(JVM Stack)

作用:每个线程都有自己的虚拟机栈,用于存储方法的局部变量、操作栈、动态链接、方法出口等信息。
特性:栈帧在每个方法调用时创建并销毁,线程的栈帧和栈内数据对其他线程不可见。

本地方法栈(Native Method Stack)

作用:类似于虚拟机栈,但专门用于处理 native 方法调用。
特性:线程的本地方法栈也是私有的,对其他线程不可见。

线程局部变量(ThreadLocal)

作用:ThreadLocal 提供线程局部变量,每个线程都有自己独立的变量副本。
特性:线程局部变量对其他线程不可见,适合用来存储线程特定的数据,如用户会话、数据库连接等。

线程共享:

堆内存(Heap Memory)

作用:用于存储对象和数组,是 Java 对象的主要存储区域。
特性:堆内存对所有线程共享,每个线程都可以访问和操作堆中的对象。因为堆是共享的,所以必须通过适当的同步机制来确保线程安全。

方法区(Method Area)(在 Java 8 及以后版本中称为元空间 Metaspace)

作用:用于存储类的信息、常量、静态变量等。
特性:方法区是所有线程共享的,类的元数据和静态变量存储在方法区中。因此,类的加载、卸载、静态变量的访问等操作需要同步,以避免线程不安全的问题。

运行时常量池(Runtime Constant Pool)

作用:方法区的一部分,存储类、接口、字段、方法的常量。
特性:运行时常量池对所有线程共享,访问和修改常量池需要考虑线程安全问题。

在方法中new 一个对象会先在堆中创建它,然后在栈内存中将变量指向堆中地址。大家可以先看看以下代码,并用说明其中的builder对象,在多线程高并发的环境下,有没有可能出现不安全的情况(也就是打印出783123123)这种情况。并说明为什么。

    public void prr() {
        StringBuilder builder = new StringBuilder();
        builder.append("783");
        gt(builder);
    }

    public void gt(Object st) {

        try {
            ((StringBuilder) st).append("123");
            System.out.println(st.toString());
        } finally {
            ((StringBuilder) st).delete(0, ((StringBuilder) st).length());
        }
    }

如果能准确回答出这个问题,那么一定堆jvm的内存有了一定的理解了。恭喜你
产生多线程问题的原因
1,要有共享资源
2,要有多线程竞争使用资源

我们可以对上面的代码增加一个测试

    public static void main(String[] args) {
        BinarySearch example = new BinarySearch();
        for (int i = 0; i < 10000; i++) {
            new Thread(example::prr).start();
        }
    }

输出结果肯定无783123123这种情况,主要原因是不是共享资源
如果我们将代码改变一下就能明显发现问题

public class BinarySearch {

    StringBuilder builder = new StringBuilder();

    public void prr() {
        builder.append("783");
        gt(builder);
    }

    public void gt(Object st) {

        try {
            ((StringBuilder) st).append("123");
            System.out.println(st.toString());
        } finally {
            ((StringBuilder) st).delete(0, ((StringBuilder) st).length());
        }
    }

    public static void main(String[] args) {
        BinarySearch example = new BinarySearch();
        for (int i = 0; i < 10000; i++) {
            new Thread(example::prr).start();
        }
    }
}

这时再进行测试就能发现问题。
分析:

主要原因是由于方法的执行是新建栈进行对局部变量表的操作进行的,而虚拟机栈为线程独享的,所以并不会产生多线程并发问题。


 

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

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

相关文章

鸿蒙 HarmonyOS NEXT端云一体化开发-云函数篇

前言 TODO&#xff1a;新建项目和应用&#xff0c;开通云函数服务&#xff08;AGC&#xff09;端侧开发&#xff1a;Arkts界面开发云测开发&#xff1a;云函数、认证服务、云存储、云数据库 一、登录 地址&#xff1a;https://id1.cloud.huawei.com/CAS/portal/loginAuth.htm…

Nginx周末部署

背景 Nginx是本人学习的一类中间件&#xff0c;上次完成了vue的搭建&#xff0c;所以顺便把项目加入Nginx吧 1. 镜像拉取与测试 查询dockerHub&#xff0c;选择最新最稳定的版本 docker pull nginx:stable-perl 执行下载 docker run -d --name mynginx -p 8080:80 -v D:\IM…

【Kubernetes】配置管理(一):ConfigMap

配置管理&#xff08;一&#xff09;&#xff1a;ConfigMap 1.配置管理2.使用 ConfigMap 管理 Pod 的配置信息2.1 创建 ConfigMap2.1.1 在命令行中通过指定 ConfigMap 的参数进行创建2.1.2 通过指定的配置文件创建 ConfigMap2.1.3 通过一个文件内的多个键值对创建 ConfigMap2.1…

C++数据结构重要知识点(3)(红黑树及其插入操作)

1.红黑树和AVL树的区别 红黑树和AVL树都是平衡树&#xff0c;都是为了解决二叉搜索树的劣势。其中&#xff0c;AVL树的左右子树的高度差不超过1&#xff0c;而红黑树的最长路径不超过最短路径的二倍&#xff0c;也就是说&#xff0c;红黑树是一种近似平衡&#xff0c;而AVL树是…

【设计模式】(万字总结)深入理解Java中的创建型设计模式

1. 前言 在软件开发的世界里&#xff0c;设计模式是一种被广泛接受并应用的解决方案。它们不仅仅是代码的设计&#xff0c;更是对问题的思考和解决的方法论。在Java开发中&#xff0c;特别是在面向对象的编程中&#xff0c;设计模式尤为重要。创建型设计模式&#xff0c;作为设…

JavaScript安全编程宝典【万字详解】

文章目录 简介基本说明特点两种使用方式在script中写使用script标签引入JS文件 数据类型介绍特殊值 运算符算数运算符赋值运算符逻辑运算符&#xff1a;条件运算符 数组的定义基本使用数组的遍历 函数含义函数定义方式基本语法代码示例 细节和注意事项 自定义对象Object形式{} …

解决mysql数据库表读取中文乱码问题

本文目录 0、省流1、问题出现2、问题排查3、结论 0、省流 在服务器上创建数据库服务时&#xff0c;使用的sql脚本加载的数据库表&#xff0c;其中脚本中有一些预设的测试数据包含中文汉字&#xff0c;由于linxu服务器控制台默认编码是lantin1&#xff0c;导致中文通过该编码方…

鸿蒙HarmonyOS开发:多种内置弹窗及自定义弹窗的详细使用指南

文章目录 一、消息提示框&#xff08;showToast&#xff09;1、导入模块2、语法3、参数4、示例5、效果 二、对话框&#xff08;showDialog&#xff09;1、导入模块2、语法3、参数4、示例5、效果 三、警告弹窗&#xff08;AlertDialog&#xff09;1、语法2、参数3、AlertDialogP…

JDBC(Java访问数据库)

Java Database Connectivity&#xff1a;Java访问数据库的解决方案 JDBC定义了一套标准接口&#xff0c;即访问数据库的通用API&#xff0c; 不同的数据库厂商根据各自数据库的特点去实现这些接口。 JDBC希望用相同的方式访问不同的数据库&#xff0c;让具体的数据库操作与数…

科普文:科普文:springcloud之-Hystrix服务容错

Hystrix概念 Hystrix 服务容错保护 的概念和说明 这就是大名鼎鼎的&#xff1a;豪猪 豪猪的英文就是&#xff1a;Hystrix&#xff0c;国外一些大牛的程序员在给自己的架构起名字的时候&#xff0c;往往就这么特别。哪天咱们中国人自己也能写出些架构&#xff0c;咱们就按照中…

⚒linux通过shell脚本上传文件至minio中

&#x1f534;大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 前言 之前数据库是备份到了七牛云上了&#xff0c;但是眼看着数据库文件越来越大&#xff0c;七牛云里面的余额越来越少&#xff0c;所以&#xff0c;转移阵地。 家里的nas&…

昇思25天学习打卡营第20天|munger85

GAN图像生成 生成对抗网络中是为了让我们生成的东西向期望的那样&#xff0c;就是为了让生成的东西很像&#xff0c;真的&#xff0c;例如用它来画画。就是描述整个网络的逻辑和目的&#xff0c;它有两部分组成&#xff0c;一个是生成器&#xff0c;一个是辨别器。他希望的是辨…

C++程序编程中的 SetWindowLong 函数的几个常见用途(附源码)

目录 1、API函数SetWindowLong说明 2、修改窗口风格 3、给窗口指定新的窗口消息处理函数,以拦截窗口消息 4、可以给窗口设置关联的UserData数据,方便在窗口内部使用这些数据 5、64位程序中需要使用SetWindowLongPtr 6、最后 C++软件异常排查从入门到精通系列教程(专栏…

Sping项目只能勾选17和21 (已解决) 导致的后续Invalid bound statement (not found):

问题发现 今天创建项目的时候发现 idea初始化spring的时候选择不了Java8 解决方案:替换URL为 https://start.aliyun.com/ 将IDEA页面创建Spring项目&#xff0c;其实是访问spring initializr去创建项目。故我们可以通过阿里云国服去间接创建Spring项目。 将https://start.spr…

TortoiseSVN安装使用教程(超详细)

目录 前言1. 下载2. 安装2.1 安装TortoiseSVN&#xff08;看图操作&#xff09;2.2 安装语言包&#xff08;看图操作&#xff09; 3. 使用3.1 版本库浏览器3.2 其他教程 前言 TortoiseSVN&#xff1a;&#xff08;俗称小乌龟&#xff09;Subversion版本控制系统的一个免费开源客…

Pytorch基础:Tensor的view方法(非连续张量也可以使用view)

相关阅读 Pytorch基础https://blog.csdn.net/weixin_45791458/category_12457644.html?spm1001.2014.3001.5482 在Pytorch中&#xff0c;view是Tensor的一个重要方法&#xff0c;用于返回一个改变了形状&#xff0c;但数据和数据的顺序与原来一致的新张量&#xff0c;但是新张…

夸克Android一面凉经(2024)

夸克Android一面凉经(2024) 笔者作为一名双非二本毕业7年老Android, 最近面试了不少公司, 目前已告一段落, 整理一下各家的面试问题, 打算陆续发布出来, 供有缘人参考。今天给大家带来的是《夸克Android一面凉经(2024)》。 面试职位: 智能信息-客户端开发工程师-夸克小说 技术一…

20240728 每日AI必读资讯

Google Gemini 聊天机器人更新 可以免费使用Gemini 1.5 Flash 1. 引入Gemini 1.5 Flash模型&#xff1a; • 提供更快和更高质量的响应。 • 提升推理和图像理解能力。 • 上下文窗口扩大到 32Ktokens&#xff0c;允许进行更长的对话和处理更复杂的问题。 • 即将支持通过 Goo…

【你也能从零基础学会网站开发】 SQL结构化查询语言应用基础-- SQL Server数据库开发创建表之FOREIGN KEY外键约束完全详解最详细!

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;程序猿、设计师、技术分享 &#x1f40b; 希望大家多多支持, 我们一起学习和进步&#xff01; &#x1f3c5; 欢迎评论 ❤️点赞&#x1f4ac;评论 &#x1f4c2;收藏 &#x1f4c2;加关注 浅谈FOREIGN K…

故障诊断 | CNN-LSSVM卷积神经网络结合最小二乘支持向量机故障诊断(Matlab)

效果一览 文章概述 故障诊断 | CNN-LSSVM卷积神经网络结合最小二乘支持向量机故障诊断(Matlab) 模型描述 使用CNN进行特征提取: 使用CNN模型对数据进行训练,通常是图像数据。 通过CNN的卷积层和池化层提取图像的特征。 将提取到的特征作为输入,可以是全连接层的输出或者卷…