深入解析Java虚拟机(JVM)内存模型-全面掌握JVM内存管理

Java虚拟机(JVM)的内存模型是Java开发者必须掌握的核心知识之一。无论你是刚入门的新手,还是经验丰富的老手,深入理解JVM内存模型都能帮助你写出更高效、更稳定的Java程序。本文将带你全面剖析JVM内存模型的各个组成部分,深入探讨其工作原理,并通过实例讲解如何进行内存优化。让我们开始这段揭秘JVM内存奥秘的旅程吧!
image.png

目录

    • 1. JVM内存模型概述
    • 2. 堆(Heap)
      • 2.1 堆的结构
      • 2.2 对象的生命周期
      • 2.3 代码示例
    • 3. 方法区(Method Area)
      • 3.1 方法区的特点
      • 3.2 存储内容
      • 3.3 代码示例
    • 4. 程序计数器(Program Counter Register)
      • 4.1 程序计数器的特点
      • 4.2 作用
      • 4.3 代码示例
    • 5. 本地方法栈(Native Method Stack)
      • 5.1 本地方法栈的特点
      • 5.2 作用
      • 5.3 代码示例
    • 6. 虚拟机栈(VM Stack)
      • 6.1 虚拟机栈的特点
      • 6.2 栈帧结构
      • 6.3 代码示例
    • 7. JVM内存模型的工作原理
      • 7.1 对象的创建过程
      • 7.2 垃圾回收
      • 7.3 内存分配与回收策略
      • 7.4 代码示例
    • 8. JVM内存模型调优技巧
      • 8.1 堆大小调整
      • 8.2 新生代和老年代比例调整
      • 8.3 垃圾回收器选择
      • 8.4 代码优化
      • 8.5 代码示例
    • 9. JVM内存模型常见问题及解决方案
      • 9.1 内存泄漏(Memory Leak)
      • 9.2 OutOfMemoryError
      • 9.3 StackOverflowError
    • 10. JVM内存模型的未来发展趋势
      • 10.1 ZGC (Z Garbage Collector)
      • 10.2 Shenandoah GC
      • 10.3 Graal VM
      • 10.4 Project Valhalla
    • 11. 实践案例:JVM内存模型在大型项目中的应用
      • 11.1 项目背景
      • 11.2 内存配置
      • 11.3 关键代码优化
        • 11.3.1 商品缓存
        • 11.3.2 订单处理
        • 11.3.3 用户会话管理
      • 11.4 性能监控
        • 11.4.1 JMX监控
        • 11.4.2 日志分析
      • 11.5 内存泄漏检测
    • 12. 总结与展望
      • 12.1 关键要点回顾
      • 12.2 未来展望
      • 12.3 实践建议

1. JVM内存模型概述

JVM内存模型是Java虚拟机管理内存的方式,它定义了Java程序在运行时如何存储和访问数据。理解JVM内存模型对于编写高效的Java代码、诊断内存相关问题以及优化应用性能至关重要。

JVM内存模型主要包含以下几个区域:

  1. 堆(Heap)
  2. 方法区(Method Area)
  3. 程序计数器(Program Counter Register)
  4. 本地方法栈(Native Method Stack)
  5. 虚拟机栈(VM Stack)

接下来,我们将详细介绍每个区域的特点和作用。
image.png

2. 堆(Heap)

堆是JVM中最大的一块内存区域,用于存储对象实例。几乎所有的对象实例都在这里分配内存。
image.png

2.1 堆的结构

堆可以细分为以下几个部分:

  1. 新生代(Young Generation)
    • Eden空间
    • From Survivor空间
    • To Survivor空间
  2. 老年代(Old Generation)
    image.png

2.2 对象的生命周期

  1. 对象优先在Eden区分配
  2. 大对象直接进入老年代
  3. 长期存活的对象将进入老年代

2.3 代码示例

public class HeapExample {public static void main(String[] args) {// 分配在堆上的对象String str = new String("Hello, JVM Heap!");// 大对象,可能直接分配在老年代byte[] largeArray = new byte[4 * 1024 * 1024]; // 4MBSystem.out.println(str);}
}

3. 方法区(Method Area)

方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

3.1 方法区的特点

  1. 线程共享
  2. 在JDK 8之前,方法区也被称为"永久代"(PermGen)
  3. 在JDK 8及以后,方法区被元空间(Metaspace)取代
    image.png

3.2 存储内容

  1. 类信息(类的版本、字段、方法、接口等)
  2. 运行时常量池
  3. 静态变量
  4. JIT编译后的代码
    image.png

3.3 代码示例

public class MethodAreaExample {// 静态变量存储在方法区public static final String CONSTANT = "This is a constant";public static void main(String[] args) {// 类信息和方法信息存储在方法区System.out.println(MethodAreaExample.class.getName());System.out.println(CONSTANT);}
}

4. 程序计数器(Program Counter Register)

程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。

4.1 程序计数器的特点

  1. 线程私有
  2. 唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域

4.2 作用

  1. 字节码解释器通过改变程序计数器来依次读取指令
  2. 多线程情况下,程序计数器用于记录当前线程执行的位置

4.3 代码示例

public class PCRegisterExample {public static void main(String[] args) {int a = 10;int b = 20;int c = a + b;System.out.println("Result: " + c);}
}

在这个简单的例子中,程序计数器会跟踪每一行代码的执行,确保指令能够按顺序正确执行。

5. 本地方法栈(Native Method Stack)

本地方法栈为虚拟机使用到的Native方法服务。

5.1 本地方法栈的特点

  1. 线程私有
  2. 可以固定大小,也可以动态扩展

5.2 作用

  1. 执行本地方法
  2. 管理本地方法的调用

5.3 代码示例

public class NativeMethodStackExample {// 声明本地方法public native void nativeMethod();static {// 加载包含本地方法实现的库System.loadLibrary("NativeLib");}public static void main(String[] args) {NativeMethodStackExample example = new NativeMethodStackExample();example.nativeMethod();}
}

6. 虚拟机栈(VM Stack)

虚拟机栈描述的是Java方法执行的内存模型。

6.1 虚拟机栈的特点

  1. 线程私有
  2. 生命周期与线程相同
  3. 可以固定大小,也可以动态扩展

6.2 栈帧结构

每个方法在执行时都会创建一个栈帧,栈帧中包含:

  1. 局部变量表
  2. 操作数栈
  3. 动态链接
  4. 方法出口

6.3 代码示例

public class VMStackExample {public static void main(String[] args) {method1();}public static void method1() {int x = 10;int y = 20;method2(x, y);}public static void method2(int a, int b) {int z = a + b;System.out.println("Result: " + z);}
}

在这个例子中,每个方法调用都会在虚拟机栈中创建一个新的栈帧。

7. JVM内存模型的工作原理

了解了JVM内存模型的各个组成部分,我们来看看它们是如何协同工作的。
image.png

7.1 对象的创建过程

  1. 类加载检查
  2. 分配内存
  3. 初始化零值
  4. 设置对象头
  5. 执行<init>方法

7.2 垃圾回收

JVM会自动进行垃圾回收,主要包括以下步骤:

  1. 标记(Mark):识别哪些对象还在使用,哪些可以回收
  2. 清除(Sweep):回收垃圾对象占用的空间
  3. 整理(Compact):整理内存碎片(部分垃圾回收算法会执行此步骤)

7.3 内存分配与回收策略

  1. 对象优先在Eden区分配
  2. 大对象直接进入老年代
  3. 长期存活的对象将进入老年代
  4. 动态对象年龄判定
  5. 空间分配担保

7.4 代码示例

public class MemoryAllocationExample {private static final int _1MB = 1024 * 1024;public static void main(String[] args) {byte[] allocation1, allocation2, allocation3, allocation4;allocation1 = new byte[2 * _1MB];allocation2 = new byte[2 * _1MB];allocation3 = new byte[2 * _1MB];allocation4 = new byte[4 * _1MB]; // 可能会触发一次Minor GC}
}

8. JVM内存模型调优技巧

理解JVM内存模型后,我们可以采取一些策略来优化Java应用的性能。

8.1 堆大小调整

  • -Xms: 设置堆的初始大小
  • -Xmx: 设置堆的最大大小
java -Xms1g -Xmx2g YourApplication

8.2 新生代和老年代比例调整

  • -XX:NewRatio: 设置新生代和老年代的比例
java -XX:NewRatio=2 YourApplication

8.3 垃圾回收器选择

  • -XX:+UseParallelGC: 使用并行垃圾回收器
  • -XX:+UseConcMarkSweepGC: 使用CMS垃圾回收器
  • -XX:+UseG1GC: 使用G1垃圾回收器
java -XX:+UseG1GC YourApplication

8.4 代码优化

  1. 及时释放不再使用的对象引用
  2. 使用字符串常量池
  3. 避免创建过多临时对象

8.5 代码示例

public class MemoryOptimizationExample {public static void main(String[] args) {// 使用StringBuilder代替String连接StringBuilder sb = new StringBuilder();for (int i = 0; i < 1000; i++) {sb.append(i);}String result = sb.toString();// 使用try-with-resources自动关闭资源try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {String line;while ((line = reader.readLine()) != null) {System.out.println(line);}} catch (IOException e) {e.printStackTrace();}}
}

9. JVM内存模型常见问题及解决方案

在实际开发中,我们可能会遇到各种与JVM内存相关的问题。以下是一些常见问题及其解决方案。
image.png

9.1 内存泄漏(Memory Leak)

问题描述:程序中的某些对象不再使用,但仍然被引用,导致无法被垃圾回收。

解决方案:

  1. 使用内存分析工具(如Eclipse Memory Analyzer)定位泄漏对象
  2. 检查并修复代码中的逻辑错误,确保不再使用的对象被正确释放
  3. 使用弱引用(WeakReference)来存储可能会被长期持有的对象

代码示例:

import java.lang.ref.WeakReference;public class MemoryLeakSolutionExample {private static class LargeObject {private byte[] data = new byte[100 * 1024 * 1024]; // 100MB}public static void main(String[] args) {// 使用弱引用WeakReference<LargeObject> weakRef = new WeakReference<>(new LargeObject());// 在需要时使用对象LargeObject obj = weakRef.get();if (obj != null) {// 使用对象}// 当内存不足时,weakRef引用的对象可能会被回收System.gc();// 再次检查对象是否还存在obj = weakRef.get();if (obj == null) {System.out.println("LargeObject has been garbage collected");}}
}

9.2 OutOfMemoryError

问题描述:当JVM没有足够的内存来分配对象时,会抛出OutOfMemoryError。

解决方案:

  1. 增加堆内存大小(-Xmx参数)
  2. 检查并修复可能的内存泄漏
  3. 优化代码,减少内存使用

代码示例:

import java.util.ArrayList;
import java.util.List;public class OutOfMemoryErrorSolutionExample {public static void main(String[] args) {List<byte[]> list = new ArrayList<>();try {while (true) {list.add(new byte[1024 * 1024]); // 每次添加1MB}} catch (OutOfMemoryError e) {System.out.println("OutOfMemoryError caught");// 释放一些内存int halfSize = list.size() / 2;list.subList(halfSize, list.size()).clear();System.gc();// 继续执行其他操作System.out.println("Recovered from OutOfMemoryError, current list size: " + list.size());}}
}

9.3 StackOverflowError

问题描述:当线程栈空间不足时,通常是由于递归调用层数过深导致的。

解决方案:

  1. 增加线程栈大小(-Xss参数)
  2. 优化递归算法,考虑使用迭代方式重写

代码示例:

public class StackOverflowErrorSolutionExample {public static void main(String[] args) {try {recursiveMethod(0);} catch (StackOverflowError e) {System.out.println("StackOverflowError caught");// 使用迭代方式重写iterativeMethod(1000000);}}// 可能导致StackOverflowError的递归方法private static void recursiveMethod(int n) {System.out.println("Recursive call #" + n);recursiveMethod(n + 1);}// 使用迭代替代递归private static void iterativeMethod(int n) {for (int i = 0; i < n; i++) {System.out.println("Iterative call#" + i);}}
}

10. JVM内存模型的未来发展趋势

随着Java技术的不断发展,JVM内存模型也在不断演进。以下是一些值得关注的趋势和新特性:
image.png

10.1 ZGC (Z Garbage Collector)

ZGC是一种可扩展的低延迟垃圾收集器,旨在支持TB级别的堆内存,同时保持毫秒级的暂停时间。

特点:

  1. 并发收集
  2. 单代设计
  3. 基于区域的内存管理
  4. 可扩展性强

使用ZGC的示例:

java -XX:+UseZGC -Xmx16g YourApplication

10.2 Shenandoah GC

Shenandoah是另一种低延迟垃圾收集器,它通过与应用程序并发执行来减少GC暂停时间。

特点:

  1. 并发整理
  2. 独立于分代
  3. 适用于大内存堆

使用Shenandoah GC的示例:

java -XX:+UseShenandoahGC -Xmx16g YourApplication

10.3 Graal VM

Graal VM是一个高性能JDK发行版,它引入了新的即时编译器(JIT)和多语言运行时。

特点:

  1. 高性能JIT编译
  2. 支持多种编程语言
  3. 提供了Native Image功能,可以将Java应用编译成本地可执行文件

使用Graal VM的示例:

public class GraalVMExample {public static void main(String[] args) {long start = System.nanoTime();// 计算密集型操作double sum = 0;for (int i = 0; i < 1_000_000_000; i++) {sum += Math.sin(i);}long end = System.nanoTime();System.out.printf("Result: %.2f, Time: %.2f ms%n", sum, (end - start) / 1_000_000.0);}
}

运行命令:

$GRAALVM_HOME/bin/java GraalVMExample

10.4 Project Valhalla

Project Valhalla是一个正在进行中的OpenJDK项目,旨在引入值类型和泛型特化。

特点:

  1. 值类型:可以像原始类型一样高效,同时具有对象的抽象能力
  2. 泛型特化:允许泛型代码利用原始类型的性能优势

示例(注意:语法可能会随项目进展而改变):

value class Point {int x;int y;
}public class ValhallaExample {public static void main(String[] args) {Point p = new Point(3, 4);System.out.println("Point: (" + p.x + ", " + p.y + ")");List<int> intList = new ArrayList<>();intList.add(1);intList.add(2);intList.add(3);int sum = 0;for (int i : intList) {sum += i;}System.out.println("Sum: " + sum);}
}

11. 实践案例:JVM内存模型在大型项目中的应用

image.png

为了更好地理解JVM内存模型在实际项目中的应用,让我们来看一个大型电商平台的案例。

11.1 项目背景

假设我们正在为一个大型电商平台开发后端系统,该系统需要处理大量并发请求,包括商品查询、订单处理、用户认证等功能。

11.2 内存配置

根据系统的需求和硬件资源,我们可以进行以下配置:

java -server -Xms8g -Xmx8g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=45 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log YourApplication

这里我们:

  • 使用服务器模式
  • 设置最小和最大堆大小为8GB
  • 使用G1垃圾收集器
  • 设置最大GC暂停时间为200毫秒
  • 设置堆占用率达到45%时开始并发标记周期
  • 开启GC日志记录

11.3 关键代码优化

11.3.1 商品缓存

为了减少数据库压力并提高响应速度,我们可以使用内存缓存来存储热门商品信息。

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;public class ProductCache {private static final Cache<Long, Product> cache = CacheBuilder.newBuilder().maximumSize(10000).build();public static Product getProduct(long productId) {Product product = cache.getIfPresent(productId);if (product == null) {product = loadProductFromDatabase(productId);cache.put(productId, product);}return product;}private static Product loadProductFromDatabase(long productId) {// 从数据库加载商品信息}
}
11.3.2 订单处理

处理订单时,我们需要注意内存使用,特别是在处理大量并发订单时。

public class OrderProcessor {private static final int BATCH_SIZE = 1000;public void processOrders(List<Order> orders) {List<Order> batch = new ArrayList<>(BATCH_SIZE);for (Order order : orders) {batch.add(order);if (batch.size() >= BATCH_SIZE) {processBatch(batch);batch.clear();}}if (!batch.isEmpty()) {processBatch(batch);}}private void processBatch(List<Order> batch) {// 批量处理订单}
}
11.3.3 用户会话管理

为了高效管理用户会话,我们可以使用分布式缓存系统如Redis,并在JVM中保持一个小的本地缓存。

import redis.clients.jedis.Jedis;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;public class UserSessionManager {private static final Cache<String, UserSession> localCache = CacheBuilder.newBuilder().maximumSize(10000).build();private static final Jedis redisClient = new Jedis("localhost");public static UserSession getUserSession(String sessionId) {UserSession session = localCache.getIfPresent(sessionId);if (session == null) {String sessionData = redisClient.get(sessionId);if (sessionData != null) {session = deserializeSession(sessionData);localCache.put(sessionId, session);}}return session;}public static void updateUserSession(String sessionId, UserSession session) {localCache.put(sessionId, session);redisClient.set(sessionId, serializeSession(session));}private static UserSession deserializeSession(String sessionData) {// 反序列化会话数据}private static String serializeSession(UserSession session) {// 序列化会话数据}
}

11.4 性能监控

为了及时发现和解决JVM内存相关的问题,我们需要实施全面的性能监控策略。

11.4.1 JMX监控

使用JMX(Java Management Extensions)来远程监控JVM的运行状况。

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import javax.management.MBeanServer;
import javax.management.ObjectName;public class MemoryMonitor implements MemoryMonitorMBean {private final MemoryMXBean memoryMXBean;public MemoryMonitor() {memoryMXBean = ManagementFactory.getMemoryMXBean();try {MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();ObjectName name = new ObjectName("com.example:type=MemoryMonitor");mbs.registerMBean(this, name);} catch (Exception e) {e.printStackTrace();}}@Overridepublic long getHeapMemoryUsage() {MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();return heapMemoryUsage.getUsed();}@Overridepublic long getNonHeapMemoryUsage() {MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();return nonHeapMemoryUsage.getUsed();}
}interface MemoryMonitorMBean {long getHeapMemoryUsage();long getNonHeapMemoryUsage();
}
11.4.2 日志分析

定期分析GC日志,可以使用工具如GCViewer来可视化GC行为。

import java.io.File;
import java.util.logging.Logger;public class GCLogAnalyzer {private static final Logger logger = Logger.getLogger(GCLogAnalyzer.class.getName());public static void analyzeGCLog(String logFilePath) {File logFile = new File(logFilePath);if (!logFile.exists()) {logger.warning("GC log file not found: " + logFilePath);return;}// 使用GCViewer API分析日志// GCViewer gcViewer = new GCViewer();// gcViewer.loadLogFile(logFile);// GCModel model = gcViewer.getGCModel();// 输出分析结果logger.info("GC分析结果:");// logger.info("总GC次数: " + model.getGCCount());// logger.info("总GC时间: " + model.getPauseTime().getSum() + " ms");// logger.info("最长GC时间: " + model.getPauseTime().getMax() + " ms");}
}

11.5 内存泄漏检测

在大型项目中,及时发现和解决内存泄漏至关重要。我们可以使用工具如Eclipse Memory Analyzer(MAT)来分析堆转储。

import java.lang.management.ManagementFactory;
import com.sun.management.HotSpotDiagnosticMXBean;public class HeapDumpGenerator {public static void generateHeapDump(String fileName) throws Exception {HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy(ManagementFactory.getPlatformMBeanServer(),"com.sun.management:type=HotSpotDiagnostic",HotSpotDiagnosticMXBean.class);mxBean.dumpHeap(fileName, true);}public static void main(String[] args) {try {generateHeapDump("heap_dump_" + System.currentTimeMillis() + ".hprof");System.out.println("Heap dump generated successfully.");} catch (Exception e) {e.printStackTrace();}}
}

12. 总结与展望

通过深入探讨JVM内存模型,我们不仅了解了其基本结构和工作原理,还学习了如何在实际项目中应用这些知识来优化Java应用程序的性能。从堆和栈的基本概念,到垃圾回收机制,再到内存调优技巧,我们全面覆盖了JVM内存管理的各个方面。
image.png

12.1 关键要点回顾

  1. JVM内存模型的主要组成部分:堆、方法区、程序计数器、本地方法栈和虚拟机栈。
  2. 垃圾回收机制和常用的垃圾收集器。
  3. 内存分配策略和对象生命周期。
  4. 常见的内存问题(如内存泄漏、OutOfMemoryError)及其解决方案。
  5. JVM参数调优和性能监控技巧。

12.2 未来展望

随着Java技术的不断发展,我们可以期待JVM内存模型在以下方面继续演进:

  1. 更智能的自适应内存管理:未来的JVM可能会更好地根据应用程序的实际运行情况自动调整内存分配和回收策略。

  2. 更低延迟的垃圾回收:像ZGC和Shenandoah这样的低延迟垃圾收集器将继续发展,可能会成为未来JVM的标准配置。

  3. 硬件感知的内存管理:随着硬件技术的发展,JVM可能会更好地利用新型存储技术(如非易失性内存)来优化内存管理。

  4. 更好的多语言支持:随着GraalVM等技术的发展,JVM可能会更好地支持多语言混合编程,这可能会影响内存模型的设计。

  5. 云原生和容器化支持:JVM内存模型可能会进一步优化,以更好地适应云环境和容器化部署的需求。

12.3 实践建议

  1. 持续学习:JVM技术在不断发展,保持学习新特性和最佳实践的习惯。

  2. 性能优先:在设计和开发阶段就考虑内存使用和性能问题,而不是等到出现问题再解决。

  3. 工具助力:熟练使用各种JVM监控和分析工具,如JConsole、VisualVM、Eclipse MAT等。

  4. 测试驱动:编写全面的性能测试用例,模拟各种负载情况,及早发现

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#-读取测序数据的ABI文件并绘制svg格式峰图

本地环境&#xff1a;win10&#xff0c;visual studio 2022 community 目录 前言问题描述实现效果解决思路实现要点ABI文件的组织方式svg绘制问题变色碱基值 动态设置svg图像宽度 前言 本文是在已有的代码基础上进行的开发&#xff0c;前期已经实现&#xff1a; ABI文件的解析…

【从零搭建SpringBoot3.x 项目脚手架】- 1. 工程初始化

为什么会有这个系列文章 在项目开发中&#xff0c;大多项目依旧沿用的是 JDK 8 Spring Boot 2.x 系列的技术栈&#xff0c;没有Spring Boot 3.x 的上手实践机会。在个人学习探索 Spring Boot 3.x 的过程中&#xff0c;遇到多数第三方框架集成和问题排查的技术问题&#xff0c…

[极客大挑战 2019]Secret File-web

打开题目 查看源码 直接访问Archive_room.php 第二个页面是个点击框&#xff0c;这里bp抓包确认&#xff1b;若是直接SECRET&#xff0c;会跳到end.php 直接访问secr3t.php 代码审计一下 playload&#xff1a;secr3t.php?fileflag.php 改为php协议读取权限 secr3t.php?f…

[图解]SysML建模电磁轨道炮-01块定义图

1 00:00:00,490 --> 00:00:04,000 我们是用EA复刻一个网络上的案例 2 00:00:06,370 --> 00:00:09,240 电磁轨道炮&#xff0c;它的原理很简单 3 00:00:09,490 --> 00:00:10,960 初中物理就可以理解 4 00:00:11,670 --> 00:00:14,010 首先&#xff0c;电流形成磁…

polyfit曲线拟合

一、简介 polyfit函数是matlab中用于进行曲线拟合的一个函数。其数学基础是最小二乘法曲线拟合原理。曲线拟合&#xff1a;已知离散点上的数据集&#xff0c;即已知在点集上的函数值&#xff0c;构造一个解析函数&#xff08;其图形为一曲线&#xff09;使在原离散点上尽可能接…

快讯 | 苹果携手OpenAI,ChatGPT即将登陆iOS 18

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

【反序列化漏洞】serial靶机详解

一、安装靶机 首先创建新的虚拟机。 然后选择客户机版本为Ubuntu 64位。 然后选择使用现有磁盘&#xff0c;选择下载的vmdk磁盘文件即可。剩下的都是默认 二、信息收集 发现主机192.168.204.143 访问 扫描端口nmap -A 192.168.204.143 -p-&#xff0c;发现只有ssh:22和http:8…

Java:线程安全

引子 首先来看一段代码: private static int count 0;public static void main(String[] args) throws InterruptedException {Thread t1 new Thread(()->{for (int i 0; i < 50000; i) {count;}});Thread t2 new Thread(()->{for (int i 0; i < 50000; i) {…

如何解决C#字典的线程安全问题

前言 我们在上位机软件开发过程中经常需要使用字典这个数据结构&#xff0c;并且经常会在多线程环境中使用字典&#xff0c;如果使用常规的Dictionary就会出现各种异常&#xff0c;本文就是详细介绍如何在多线程环境中使用字典来解决线程安全问题。 1、非线程安全举例 Dictio…

Vue+live2d实现虚拟人物互动(一次体验叙述)

目录 故事的开头&#xff1a; 最终的实现效果&#xff1a; 实现步骤&#xff1a; 第一步&#xff1a;下载重要文件 第二步&#xff1a;创建vue项目文件&#xff0c;将刚下载文件拷贝到public目录下 第三步&#xff1a;在index.html文件中引入js 第四步&#xff1a;使用&…

【数据结构算法经典题目刨析(c语言)】顺序表和链表的区别(图文详解)

&#x1f493; 博客主页&#xff1a;C-SDN花园GGbond ⏩ 文章专栏&#xff1a;数据结构经典题目刨析(c语言) 目录 顺序表和链表的区别 一、底层存储空间 二、插入和删除操作 三、随机访问 四、空间利用率 五、应用场景 六、高速缓存 为什么顺序表的缓存利用率高于链表呢…

设计界的新宠:5款热门UI在线设计软件评测

随着用户界面设计行业的蓬勃发展&#xff0c;越来越多的设计师进入用户界面设计。选择一个方便的用户界面设计工具尤为重要&#xff01;除了传统的用户界面设计工具&#xff0c;在线用户界面设计工具也受到越来越多设计师的青睐。这种不受时间、地点、计算机配置限制的工作方法…

OpenCV||超详细的图像边缘检测

一、基本概念 1.图像边缘检测目的 特征提取&#xff1a;边缘是图像中亮度变化最显著的部分&#xff0c;它们通常对应于物体的轮廓、不同区域的边界等。通过边缘检测&#xff0c;可以从图像中提取出这些重要的特征信息&#xff0c;为后续处理如图像分割、目标识别等提供基础。 …

webfunny埋点系统如何进行部署?

hello 大家webfunny埋点系统做了不少功能更新&#xff0c;平常给大家分享比较多的是**webfunny前端监控系统**&#xff0c;最近有不少技术同学来了解webfunny埋点系统&#xff0c;今天主要给大家分享下webfunny埋点系统部署&#xff0c;分为本地部署和线上部署。 还没有试用和…

字节一面面经

1.redis了解吗&#xff0c;是解决什么问题的&#xff0c;redis的应用&#xff1f; Redis 是一种基于内存的数据库&#xff0c;常用的数据结构有string、hash、list、set、zset这五种&#xff0c;对数据的读写操作都是在内存中完成。因此读写速度非常快&#xff0c;常用于缓存&…

第三期书生大模型实战营之XTuner微调个人小助手认知

基础任务 使用 XTuner 微调 InternLM2-Chat-1.8B 实现自己的小助手认知&#xff0c;记录复现过程并截图。 任务结果截图 1. 创建虚拟环境 # 安装一些必要的库 conda install pytorch2.1.2 torchvision0.16.2 torchaudio2.1.2 pytorch-cuda12.1 -c pytorch -c nvidia -y # 安…

2024华数杯数学建模竞赛选题建议+初步分析

提示&#xff1a;DS C君认为的难度&#xff1a;C<A<B&#xff0c;开放度&#xff1a;A<B<C。 综合评价来看 A题适合对机械臂和机器人运动学感兴趣的同学&#xff0c;尤其是有一定编程和优化算法基础的同学。不建议非相关专业同学选择。 B题挑战较大&#xff0…

Go语言实现多协程文件下载器

文章目录 前言流程图主函数下载文件初始化分片下载worker分发下载任务获取下载文件的大小下载文件分片错误重试项目演示最后 前言 你好&#xff0c;我是醉墨居士&#xff0c;最近在开发文件传输相关的项目&#xff0c;然后顺手写了一个多协程文件下载器&#xff0c;代码非常精…

用于遥感数据处理的python脚本

编辑&#xff1a;我不爱机器学习 今天给大家分享一组用于遥感处理的 python 脚本。 作者使用基于无人机的智利中南部泥炭地的高光谱图像。该图像有 41 个波段&#xff08;10 nm 宽&#xff09;&#xff0c;范围为 480-880 nm&#xff0c;像素大小为 10 cm。绿点对应于测量生物…

【Python系列】Python 协程:并发编程的新篇章

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…