当前位置: 首页 > news >正文

深入理解 Java 内存管理:堆和栈

深入理解 Java 内存管理:堆和栈的全面解析

在 Java 编程语言中,内存管理是一个至关重要的概念,其中堆(Heap)和栈(Stack)是两个核心的内存区域。理解它们的工作原理、用途以及它们在程序执行过程中的角色,对于编写高效、健壮的 Java 应用程序至关重要。本文将深入探讨 Java 堆和栈,解释它们的概念、特性、以及在程序执行中的作用。

一、Java 堆(Heap)

1. 概念

Java 堆是 Java 虚拟机(JVM)用于存储所有对象实例和数组的内存区域。它是 Java 内存管理的核心部分,负责为应用程序提供动态内存分配。每当你使用 new 关键字创建一个对象时,该对象就会被分配到堆中。堆是一个共享的内存池,所有线程都可以访问它。由于其动态分配的特性,堆的大小可以在程序运行时动态调整。堆内存的管理由 Java 的自动垃圾回收机制负责,这意味着程序员不需要手动释放内存。

2. 特性

  • 动态内存分配

    • 堆内存的大小可以在程序运行时动态调整。JVM 启动时会根据配置参数设置初始堆大小和最大堆大小(通过 -Xms-Xmx 参数)。

    • 动态内存分配使得 Java 程序可以灵活适应不同的内存需求,特别是在需要频繁创建和销毁对象的应用程序中。

      public class DynamicHeapAllocation {public static void main(String[] args) {// 动态创建多个对象for (int i = 0; i < 1000; i++) {Person person = new Person("Person " + i, i);// 这里没有显式释放内存,JVM 会自动管理}}
      }
      

      在这个示例中,我们动态创建了 1000 个 Person 对象。JVM 会根据需要动态调整堆的大小,以适应这些对象的内存需求。

  • 垃圾回收(Garbage Collection)

    • Java 提供了自动垃圾回收机制来管理堆内存。垃圾回收器会自动检测不再被引用的对象,并回收其占用的内存。这减少了内存泄漏的可能性。

    • 垃圾回收过程可能会导致程序暂停(Stop-the-World),这会影响应用程序的性能。因此,理解垃圾回收的工作原理,并根据应用程序的需求进行调优,是 Java 性能优化的重要组成部分。

    • 常见的垃圾回收算法包括:

      • 标记-清除(Mark-Sweep):标记所有存活的对象,然后清除未标记的对象。
      • 标记-整理(Mark-Compact):标记所有存活的对象,然后移动它们以整理内存空间。
      • 复制(Copying):将存活的对象复制到新的内存区域,以实现内存整理。
      public class GarbageCollectionExample {public static void main(String[] args) {createObjects();System.gc(); // 显式请求垃圾回收}private static void createObjects() {for (int i = 0; i < 100; i++) {Person person = new Person("Person " + i, i);}// 超出作用域后,person 对象不再被引用}
      }
      

      在这个示例中,createObjects 方法创建了 100 个 Person 对象。当方法执行完毕后,这些对象不再被引用,JVM 的垃圾回收器会自动回收它们占用的内存。System.gc() 只是一个建议,具体的垃圾回收时机由 JVM 决定。

  • 线程共享

    • 堆内存是线程共享的,所有线程都可以访问堆内存中的对象。这种共享特性使得对象可以在不同线程之间共享,但也需要注意线程安全问题。
    • 在多线程环境中,多个线程可能同时访问和修改堆中的对象,因此需要使用同步机制(如 synchronized 关键字或 java.util.concurrent 包中的工具)来确保线程安全。
    public class ThreadSharedHeap {public static void main(String[] args) {Person sharedPerson = new Person("Shared", 25);Thread thread1 = new Thread(() -> {System.out.println("Thread 1: " + sharedPerson.getName());});Thread thread2 = new Thread(() -> {System.out.println("Thread 2: " + sharedPerson.getName());});thread1.start();thread2.start();}
    }

    在这个示例中,sharedPerson 对象被多个线程访问。由于堆是线程共享的,所以两个线程可以同时访问 sharedPerson 对象。

3. 内部结构

Java 堆通常被分为几个不同的区域,以优化内存分配和垃圾回收:

  • 年轻代(Young Generation)

    • 包含 Eden 区和两个 Survivor 区(通常称为 S0S1)。

    • 大多数新创建的对象会被分配到 Eden 区。对象在 Eden 区存活过一次垃圾回收后,会被移动到 Survivor 区。

    • 年轻代使用复制算法进行垃圾回收(称为 Minor GC),这种算法效率高,因为大多数对象都是短命的。

      public class YoungGenerationExample {public static void main(String[] args) {for (int i = 0; i < 10000; i++) {// 这些短命对象会被分配到 Eden 区String temp = new String("Temporary " + i);}// Minor GC 会清理这些对象}
      }
      

      在这个示例中,创建了大量的短命对象,这些对象会被分配到年轻代的 Eden 区。由于对象生命周期短,Minor GC 会很快回收这些对象。

  • 老年代(Old Generation)

    • 存储从年轻代晋升过来的长生命周期的对象。

    • 老年代使用标记-整理或标记-清除算法进行垃圾回收(称为 Major GC 或 Full GC),这种回收通常比年轻代的回收更耗时。

      public class OldGenerationExample {public static void main(String[] args) {// 长生命周期对象List<Person> people = new ArrayList<>();for (int i = 0; i < 1000; i++) {people.add(new Person("LongLived " + i, i));}// 这些对象可能会晋升到老年代}
      }

      在这个示例中,people 列表持有对 Person 对象的引用,导致这些对象有较长的生命周期,可能会被晋升到老年代。

  • 永久代(PermGen)/元空间(Metaspace)

    • 存储类的元数据,如类定义、方法等。JDK 8 及以后版本使用元空间替代了永久代。
    • 元空间不在堆中,而是使用本地内存。
    public class MetaspaceExample {public static void main(String[] args) {// JDK 8 及以后,类的元数据存储在元空间Class<?> clazz = MetaspaceExample.class;System.out.println("Class loaded: " + clazz.getName());}
    }
    

    在这个示例中,new Person("New Person", 20) 创建了一个对象并在堆中分配内存。JVM 找到足够大的空闲内存块来存储这个对象,并返回一个指向该内存块的引用。

4. 示例

public class HeapExample {public static void main(String[] args) {// 创建一个对象并将其分配到堆中Person person = new Person("Alice", 30);// 调用对象的方法person.sayHello();}
}class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public void sayHello() {System.out.println("Hello, my name is " + name);}
}

在这个示例中,new Person("Alice", 30) 会在堆中创建一个新的 Person 对象。person 变量是一个引用,存储在栈中,指向堆中的对象。堆中的对象在程序运行期间可以被多个线程访问。

5. 执行过程

  • 对象创建

    • new 操作符被调用时,Java 虚拟机(JVM)会在堆中分配内存以存储新对象。JVM 会找到足够大的空闲内存块来存储对象,并返回一个指向该内存块的引用。
    • JVM 使用不同的分配策略(如指针碰撞或空闲列表)来有效地管理内存。
    public class ObjectCreationExample {public static void main(String[] args) {// 创建对象并分配到堆中Person person = new Person("New Person", 20);System.out.println(person);}
    }

    在这个示例中,new Person("New Person", 20) 创建了一个对象并在堆中分配内存。JVM 找到足够大的空闲内存块来存储这个对象,并返回一个指向该内存块的引用。

  • 垃圾回收

    • JVM 的垃圾回收器会自动检测不再被引用的对象,并回收其占用的内存。
    • 垃圾回收的具体实现可能有所不同,常见的算法包括标记-清除、标记-整理和复制等。
    • 垃圾回收器的选择和调优是 Java 性能优化的重要方面,开发者可以通过 JVM 参数(如 -XX:+UseG1GC)来指定使用的垃圾回收器。
    public class GarbageCollectorExample {public static void main(String[] args) {for (int i = 0; i < 100; i++) {createTemporaryObject();}// JVM 的垃圾回收器会自动回收不再被引用的对象}private static void createTemporaryObject() {Person tempPerson = new Person("Temp", 30);// tempPerson 超出作用域后,不再被引用}
    }
    

在这个示例中,createTemporaryObject 方法创建了一个临时对象 tempPerson。当方法执行完毕后,tempPerson 超出作用域,不再被引用,垃圾回收器会回收其占用的内存。

6. 性能优化

  • 调整堆大小:根据应用程序的内存需求调整堆的初始大小和最大大小,以减少垃圾回收的频率和停顿时间。
# 在启动 JVM 时调整堆的初始大小和最大大小
java -Xms512m -Xmx1024m MyApplication

在这个示例中,使用 -Xms-Xmx 参数调整堆的初始大小和最大大小,以减少垃圾回收的频率和停顿时间

  • 选择合适的垃圾回收器:根据应用程序的特性选择合适的垃圾回收器(如 G1、CMS、ZGC 等),以优化性能。
# 使用 G1 垃圾回收器
java -XX:+UseG1GC MyApplication
  • 监控和调优:使用工具(如 JConsole、VisualVM、GC logs)监控堆的使用情况和垃圾回收的性能,并进行调优。
# 使用 JConsole 监控 JVM 的性能
jconsole

通过深入理解 Java 堆的结构和工作原理,开发者可以更好地管理内存,优化程序性能,并避免常见的内存问题,如内存泄漏和高延迟的垃圾回收

二、Java 栈(Stack)

1. 概念

Java 栈是用于存储方法调用和局部变量的内存区域。每个线程都有自己的栈,用于存储线程执行方法的调用信息,包括局部变量、方法参数、返回地址等。栈的操作遵循后进先出(LIFO)原则。

2. 特性

  • 线程私有:每个线程都有自己的栈,因此栈中的数据是线程私有的。不同线程的栈之间互不影响,这使得栈上的数据天然是线程安全的。
  • 自动管理:栈内存由 JVM 自动管理,方法调用结束后,栈帧会自动销毁。程序员无需担心栈内存的释放问题。
  • 快速访问:由于栈是 LIFO 结构,栈的访问速度非常快。方法调用和返回的开销很小,这使得栈非常适合用于存储临时数据和方法调用信息。

3. 示例

public class StackExample {public static void main(String[] args) {int number = 10; // 局部变量,存储在栈中System.out.println(factorial(number));}public static int factorial(int n) {if (n == 0) {return 1;} else {return n * factorial(n - 1);}}
}

在这个示例中,number 是一个局部变量,存储在栈中。当 factorial 方法被调用时,会在栈中创建一个新的栈帧来存储方法的参数 n 和返回地址。每次递归调用都会创建一个新的栈帧。

4. 执行过程

  • 方法调用:每次方法调用时,JVM 都会在栈中创建一个新的栈帧,用于存储方法的局部变量和参数。栈帧还包含返回地址,以便方法执行完毕后能够返回调用者。
  • 方法返回:方法执行完毕后,栈帧会被自动销毁,释放内存。返回地址用于将控制权交还给调用方法的代码。

三、堆与栈的对比

1. 内存分配

  • :用于动态分配对象内存,大小可以动态调整。适合需要灵活内存管理的场景,但需要注意垃圾回收对性能的影响。
  • :用于静态分配方法调用和局部变量,大小固定,自动管理。适合用于存储临时数据和方法调用信息。

2. 访问速度

  • :由于需要动态分配和垃圾回收,访问速度较慢。堆内存的分配和回收可能会导致程序性能的波动。
  • :由于是 LIFO 结构,访问速度快。栈内存的分配和释放非常高效,适合频繁的函数调用和返回。

3. 线程安全

  • :线程共享,需注意同步。多个线程同时访问堆中的同一个对象时,需要使用同步机制来保证线程安全。
  • :线程私有,天然线程安全。栈上的数据仅能被所属线程访问,不存在竞争条件。

四、常见问题

1. 内存泄漏

尽管 Java 提供了垃圾回收机制,但不当的对象引用管理仍可能导致内存泄漏。例如,长时间持有对不再需要的对象的引用,或者使用缓存而不及时清理,都可能导致内存泄漏。

2. 栈溢出

递归调用过深或方法调用链过长可能导致栈溢出(StackOverflowError)。在设计递归算法时,必须确保递归深度受控,以避免栈溢出。

五、总结

理解 Java 的堆和栈对于编写高效的 Java 应用程序至关重要。堆用于动态分配对象内存,支持灵活的内存管理,而栈用于管理方法调用和局部变量,提供快速的访问速度。合理使用堆和栈可以提高程序的性能和稳定性。在编写 Java 程序时,开发者应注意对象的生命周期和方法调用深度,以避免内存泄漏和栈溢出等问题。

相关文章:

深入理解 Java 内存管理:堆和栈

深入理解 Java 内存管理&#xff1a;堆和栈的全面解析 在 Java 编程语言中&#xff0c;内存管理是一个至关重要的概念&#xff0c;其中堆&#xff08;Heap&#xff09;和栈&#xff08;Stack&#xff09;是两个核心的内存区域。理解它们的工作原理、用途以及它们在程序执行过程…...

深度全解析开放开源大模型之BLOOM

BLOOM是 BigScience Large Open-science Open-access Mul-tilingual Language Model首字母的缩写。 BigScience 不是财团&#xff08;consortium&#xff09;&#xff0c;也不是正式成立的实体。这是一个由HuggingFace、GENCI和IDRIS发起的开放式协作组织&#xff0c;以及一个…...

下载谷歌浏览器的官方离线安装包

网址&#xff1a;https://support.google.com/chrome/answer/95346?hlzh-Hans&coGENIE.Platform%3DDesktop#zippy%2Cwindows...

ORACLE创建用户报错ORA-65096: invalid common user or role name

在高版本的oracle中创建用户时提示错误ORA-65096: invalid common user or role name&#xff0c;官网说明用户名必须使用C##或c##开头。以下方法亲测有效。 通过设置"_ORACLE_SCRIPT"参数为true来临时绕过CDB中创建用户必须以"C##"开头的限制。请注意&…...

河工oj第七周补题题解2024

A.GO LecturesⅠ—— Victory GO LecturesⅠ—— Victory - 问题 - 软件学院OJ 代码 统计 #include<bits/stdc.h> using namespace std;double b, w;int main() {for(int i 1; i < 19; i ) {for(int j 1; j < 19; j ) {char ch; cin >> ch;if(ch B) b …...

运维大屏与设备仪表盘:打造高效运维管理的视觉中枢

在快速发展的信息化时代&#xff0c;运维行业面临着前所未有的挑战。随着业务规模的不断扩大和系统复杂度的日益增加&#xff0c;如何高效、准确地监控和管理设备运行状态&#xff0c;成为运维团队亟待解决的问题。运维大屏与设备仪表盘作为运维管理的重要工具&#xff0c;为运…...

计算机视觉与医学的结合:推动医学领域研究的新机遇

目录 引言医学领域面临的发文难题计算机视觉与医学的结合&#xff1a;发展趋势计算机视觉结合医学的研究方向高区位参考文章结语 引言 计算机视觉&#xff08;Computer Vision, CV&#xff09;技术作为人工智能的重要分支&#xff0c;已经在多个领域取得了显著的应用成果&…...

使用setsockopt函数SO_BINDTODEVICE异常,Protocol not available

前言 最近在使用OLT的DHCP Server的时候发现一些异常现象&#xff0c;就是ONU发的一个vlan的discover包其他不同vlan的DHCP地址池也会收到&#xff0c;导致其他服务器也发了offer包&#xff0c;ONU同时会有多个ip地址。一开始是没有使用SO_BINDTODEVICE&#xff0c;后面查到使…...

rpm包转deb包或deb包转rpm包

Debian系&#xff08;Ubuntu、Deepin、麒麟Destop等&#xff09;用的安装包是deb的&#xff0c;Red Hat系&#xff08;CentOS、欧拉、麒麟Server等&#xff09;用的安装包是rpm的。 如果需要在Ubuntu上安装rpm&#xff0c;或需要在CentOS上安装deb&#xff0c;需要安装alien s…...

ChatGPT 和文心一言哪个更好用?

ChatGPT vs 文心一言&#xff1a;哪个更好用&#xff1f; 引言 在人工智能蓬勃发展的今天&#xff0c;聊天机器人已经成为我们生活和工作中不可或缺的一部分。你可能听说过ChatGPT和文心一言这两个热门的聊天机器人&#xff0c;它们分别来自OpenAI和百度。那么&#xff0c;究…...

T113-S3 Tina 存储类型修改

前面介绍了如何在 Tina 中添加新的板子&#xff0c;本节介绍如何修改板子存储类型。 1、确定存储类型 Tina 支持多种存储类型&#xff0c;包括 SD 卡、eMMC、SPI NAND、SPI NOR 等。在添加板子之前&#xff0c;需要确定板子使用的存储类型。 存储类型修改 在 device/config/…...

【css】基础(一)

本专栏内容为&#xff1a;前端专栏 记录学习前端&#xff0c;分为若干个子专栏&#xff0c;html js css vue等 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;css专栏 &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&#x1f69a; &a…...

Linux中inode

磁盘的空间管理 如何对磁盘空间进行管理&#xff1f; 假设在一块大小为500G的磁盘中&#xff0c;500*1024*1024524288000KB。在磁盘中&#xff0c;扇区是磁盘的基本单位&#xff08;一般大小为512byte&#xff09;&#xff0c;而文件系统访问磁盘的基本单位是4KB&#xff0c;因…...

verilog fpga 如果if语句==号后面是个表达式 运行不稳定

来自 文心一言 在Verilog中编写FPGA代码时&#xff0c;使用if语句进行条件判断是常见的操作。然而&#xff0c;当if语句中的条件判断使用的是表达式&#xff08;如后面是一个复杂的表达式&#xff09;&#xff0c;确实可能会遇到运行不稳定的问题。这通常是由于以下几个原因导…...

BFS广度优先搜索

广度优先搜索&#xff08;Breadth-First Search, BFS&#xff09;是一种用于遍历或搜索树或图的算法。 它从根节点开始&#xff0c;逐层访问每个节点&#xff0c;并在访问完一层后才访问下一层。BFS常用于寻找最短路径的问题。 下面将用实例一和实例二来实现BFS广度优先搜索 …...

uniapp 自定义导航栏增加首页按钮,仿微信小程序操作胶囊

实现效果如图 抽成组件navbar.vue&#xff0c;放入分包 <template><view class"header-nav-box":style"{height:Props.imgShow?:statusBarHeightpx,background:Props.imgShow?:Props.bgColor||#ffffff;}"><!-- 是否使用图片背景 false…...

小程序项目的基本组成结构

分类介绍 项目根目录下的文件及文件夹 pages文件夹 用来存放所有小程序的页面&#xff0c;其中每个页面都由4个基本文件组成&#xff0c;它们分别是&#xff1a; .js文件&#xff1a;页面的脚本文件&#xff0c;用于存放页面的数据、事件处理函数等 .json文件&#xff1a;…...

2020年国赛高教杯数学建模E题校园供水系统智能管理解题全过程文档及程序

2020年国赛高教杯数学建模 E题 校园供水系统智能管理 原题再现 校园供水系统是校园公用设施的重要组成部分&#xff0c;学校为了保障校园供水系统的正常运行需要投入大量的人力、物力和财力。随着科学技术的发展&#xff0c;校园内已经普遍使用了智能水表&#xff0c;从而可以…...

《C++与 OpenCV 机器学习模块:目标检测的强大融合》

在当今科技飞速发展的时代&#xff0c;目标检测技术已经成为计算机视觉领域的一颗璀璨明珠&#xff0c;广泛应用于安防监控、自动驾驶、智能图像分析等众多领域。而 C语言凭借其高效性和强大的性能&#xff0c;与 OpenCV 的机器学习模块相结合&#xff0c;为实现精准且高效的目…...

函数与模块

目录 1.函数 1.1.函数概念 1.2.函数定义 1.3.函数分类 1.4.函数参数类型 1.4.1.位置参数 1.4.2.关键字参数 1.4.3.默认值参数 1.4.4.可变参数 1.5.匿名函数 1.6.参数传递问题 2.冒泡排序 2.1.冒泡排序规则 2.2.冒泡排序实现 3.math 模块 4.random 模块 5.date…...

SQL面试题——滴滴SQL面试题 取出累计值与1000差值最小的记录

滴滴SQL面试题 取出累计值与1000差值最小的记录 今天的题目来自滴滴出行 已知有表cost_detail包含id和money两列,id为自增,请累加计算money值,并求出累加值与1000差值最小的记录。 +-----+--------+ | id | money | +-----+--------+ | 1 | 200 | | 2 | 300 …...

使用 Elastic 和 Amazon Bedrock 制作混合地理空间 RAG 应用程序

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Srinivas Pendyala, Ayan Ray 借助 Elasticsearch 及其向量数据库&#xff0c;你可以构建可配置的搜索和可信的生成式 AI (GenAI) 体验&#xff0c;这些体验可快速从原型扩展到生产。主要功能包括&#xff1a; 内…...

计算机软著个人申请指南

笔者最近申请了两本软著证书&#xff0c;结合自己的经历介绍一下。 软著登记网址&#xff1a;中国版权业务登记平台 准备工作 你的项目源码源代码统计工具 source-codes-trim&#xff1a;笔者开发自用的源码处理工具vscode插件其他的可以自己在网上搜资源 Word 申请流程 注…...

OmniParser一种用于增强视觉语言模型与用户界面交互效果的技术

OmniParser一种用于增强视觉语言模型与用户界面交互效果的技术 OmniParser的核心功能是将用户界面截图转换为结构化元素&#xff0c;这一过程涉及几个关键步骤和技术要素&#xff0c;解决了视觉语言模型&#xff08;VLMs&#xff09;在与用户界面交互时所面临的多种挑战。 1.…...

HBU深度学习作业10-BPTT

1、推导BPTT 2、推导梯度 3、分析其可能存在梯度爆炸的原因并给出解决方法 为了改善循环神经网络的长程依赖问题&#xff0c;一种非常好的解决方案是在公 式(6.50)的基础上引入门控机制来控制信息的累积速度&#xff0c;包括有选择地加入新 的信息&#xff0c;并有选择地遗忘之…...

L2G6000 - MindSearch部署实践

文章目录 MindSearch部署实践部署MindSearch到 hugging face Spaces上启动MindSearch启动后端启动前端 部署到自己的 HuggingFace Spaces上 部署MindSearch streamlit版本到Hugging Face上 MindSearch部署实践 部署MindSearch到 hugging face Spaces上 在Codespaces上选择Bla…...

CentOS 7 上安装 MySQL 8.0.40 (二进制安装)

要在 CentOS 7 上安装 MySQL 8.0.40&#xff0c;按照以下步骤操作&#xff1a; 下载安装包。 https://dev.mysql.com/downloads/mysql/ 下载之前查看系统c版本 解压安装包 首先&#xff0c;解压下载的 .tar.xz 安装包。 cd /path/to/your/downloads tar -xvf mysql-8.0…...

应用案例 | 船舶海洋: 水下无人航行器数字样机功能模型构建

水下无人航行器数字样机功能模型构建 一、项目背景 为响应水下装备系统研制数字化转型及装备系统数字样机建设的需要&#xff0c;以某型号水下无人航行器&#xff08;Underwater Unmanned Vehicle&#xff0c;UUV&#xff09;为例&#xff0c;构建UUV数字样机1.0功能模型。针对…...

Chromium CDP 开发(六):注册自己的指令(下)

引言 在这一章节中&#xff0c;我们将详细讲解如何将新定义的 TimerSend 指令和 TimerLog 事件添加到项目 的 inspector_protocol_config.json 文件中&#xff0c;从而使这些功能能够在 CDP&#xff08;Chrome DevTools Protocol&#xff09;中被识别并正常使用。 inspector_pr…...

【基础算法总结】哈希表/set/map篇

目录 一&#xff0c;哈希表简介二&#xff0c;算法原理和代码实现1.两数之和349.两个数组的交集面试题01.02.判断是否互为字符重排217.存在重复元素219.存在重复元素II692.前k个高频单词45.字母异位词分组 三&#xff0c;算法总结 一&#xff0c;哈希表简介 哈希思想是算法中一…...

数字逻辑理论题目+知识点复习

昨天考完的数字逻辑理论考试&#xff0c;啊啊啊还有实验&#xff0c;生活不易&#xff0c;且行且珍惜。 请以最大的善意对待生活(,,>᎑<,,)。...

证明网络中的流形成一个凸集

证明网络中的流形成一个凸集 步骤1&#xff1a;定义和符号步骤2&#xff1a;线性组合步骤3&#xff1a;验证容量限制步骤4&#xff1a;验证流量守恒结论示例代码&#xff08;C语言&#xff09; 在网络流理论中&#xff0c;一个流 f f f 是定义在网络图的边集上的一种函数&…...

SpringBoot3

1. 配置文件 1. 基本使用 使用 配置文件classpath:application.properties spring.jdbc.drivercom.mysql.cj.jdbc.Driver spring.jdbc.urljdbc:mysql://localhost:3306/batis spring.jdbc.usernameroot spring.jdbc.password123456使用配置文件的值&#xff1a;Value("…...

Linux之线程概念,理解和控制

Linux之线程概念&#xff0c;理解和控制 一.线程1.1线程的概念1.2线程的理解1.3线程的优缺点&#xff0c;异常和用途1.4线程和进程1.5线程的控制1.4.1线程的创建1.4.2线程的终止1.4.3线程的等待1.4.4线程的分离 一.线程 1.1线程的概念 在我们了解了进程的同时我们在学校上课时…...

系统监控——分布式链路追踪系统

摘要 本文深入探讨了分布式链路追踪系统的必要性与实施细节。随着软件架构的复杂化&#xff0c;传统的日志分析方法已不足以应对问题定位的需求。文章首先解释了链路追踪的基本概念&#xff0c;如Trace和Span&#xff0c;并讨论了其基本原理。接着&#xff0c;文章介绍了SkyWa…...

【Leetcode Top 100】146. LRU 缓存

问题背景 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 c a p a c i t y capacity capacity 初始化 LRU 缓存int get(int key) 如果关键字 k e y key key 存在于缓存中&…...

Ubuntu Server 22.04.5 LTS重启后IP被重置问题

Ubuntu Server 22.04.5 LTS重启后IP被重置问题 最近在使用Ubuntu Server 22.04做项目开发测试时发现每次重启和关机后&#xff0c;所设置的静态IP地址都会回复到安装系统时所设置的ip Ubuntu Server 22.04 官网下载地址&#xff1a;Ubuntu官方下载地址 对虚拟机下安装Ubuntu感…...

电机功率、电压与电流的换算方法

在电气工程和相关行业中&#xff0c;电机的功率、电压和电流是三个重要的基本参数。它们之间有着密切的关系&#xff0c;而理解这些关系对于电机的选型、设计和应用至关重要。本文将详细阐述这三者之间的换算关系&#xff0c;以及相关公式的应用。 一、电机功率的定义 电机功…...

【Java】反射简介

框架的核心和架构师的核心 反射和代理是重中之重 反射 反射的作用 在运行的时候由代码获取类的信息 三种获取类信息的方式&#xff1a; 对象.getClass()Class.forName("类的路径")类.class Class &#xff1a;一个用来存储类信息的类 获取类信息是获取的整体的…...

【JAVA】Java第十三节:String类(String相关方法,以及StrinBuftrer , StringBulder相关方法)

本文详细介绍了String类以及常用的String相关方法&#xff0c;以及StrinBuftrer , StringBulder相关方法的使用&#xff0c;建议有印象即可&#xff0c;不需要都记住&#xff0c;使用时去查取即可 一、创建一个String类型的变量 我们平时创建String类型的变量一般是第一种形式…...

电子信息工程自动化 基于单片机的出租车计价器设计

摘 要 出租车作为一种城市中非常重要的公共交通工具&#xff0c;他与人们的生活息息相关。所以我也设计了一款出租车计价器&#xff0c;它采用模块化设计&#xff0c;包含里程测量模块、数据存储模块、按键模块、时钟模块、显示模块、语音播报模块六大主要模块。本设计的出租车…...

CentOS 二进制安装部署MongoDB 4.0

一、安装MongoDB 1. 下载 MongoDB 二进制文件 前往 MongoDB 官方下载页面(https://www.mongodb.com/try/download/community) 选择对应版本的 tar 包。 wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.28.tgz 2. 解压并移动至目标目录 解压文件&#xff…...

SQL面试题——京东SQL面试题 合并数据

京东 合并数据 几天的题目来自知名电商平台京东 已知有数据A如下,请分别根据A生成B和C。 数据A +-----+-------+ | id | name | +-----+-------+ | 1 | aa | | 2 | aa | | 3 | aa | | 4 | d | | 5 | c | | 6 | aa | | 7 | aa | | …...

windows安装使用conda

在Windows系统上安装和使用Conda的详细步骤如下&#xff1a; 一、下载Conda安装包 访问Conda的官方网站Anaconda | The Operating System for AI&#xff0c;点击“Downloads”按钮。在下载页面&#xff0c;选择适合您系统的安装包。通常&#xff0c;对于Windows系统&#xf…...

C++知识整理day4内存管理——new和delete详解

文章目录 1.C/C内存分布2.C语言中动态内存管理&#xff1a;malloc/realloc/calloc3.C内存管理方式3.1 new/delete操作内置类型3.2 new和delete操作自定义类型 4.malloc/free和new/delete到底什么区别&#xff1f;4.1 对于自定义类型4.2 对于自定义类型4.3 总结&#xff1a;它们…...

STM32 自学笔记

摘抄于大学期间记录在QQ空间的一篇自学笔记&#xff0c;当前清理空间&#xff0c;本来想直接删除掉的&#xff0c;但是感觉有些舍不得&#xff0c;因此先搬移过来。 RAM vs ROM vs FLASH 2013-09-05记录&#xff0c;ROM和RAM指的都是半导体存储器&#xff0c;ROM是Read Only …...

spring通过RequestContextHolder获取HttpServletRequest对象

1.获取HttpServletRequest对象方法&#xff1a; public static HttpServletRequest getRequest() {ServletRequestAttributes attributes ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());assert attributes ! null;return attributes.getRequest(…...

【特殊子序列 DP】力扣1137. 第 N 个泰波那契数

泰波那契序列 Tn 定义如下&#xff1a; T0 0, T1 1, T2 1, 且在 n > 0 的条件下 Tn3 Tn Tn1 Tn2 给你整数 n&#xff0c;请返回第 n 个泰波那契数 Tn 的值。 示例 1&#xff1a; 输入&#xff1a;n 4 输出&#xff1a;4 解释&#xff1a; T_3 0 1 1 2 T_4 1 …...

tcp连接设置一个超时时间(没在操作系统层面设置)

await asyncio.open_connection(ip, port, limit1024)代码是使用了操作系统的TCP连接&#xff0c;正常TCP连接的时候会有重试机制&#xff0c;当第一个SYN没有回复的时候&#xff0c;会再重试4次&#xff0c;每次间隔1s, 2s&#xff0c;4s, 8s&#xff0c;我觉得太慢了&#xf…...

03、Node.js安装及环境配置

1.下载node.js 下载地址&#xff1a;Node.js 2.安装 2.1 自定义安装路径&#xff08;可以选择默认&#xff09; 下图根据本身的需要进行&#xff0c;我选择了默认Node.js runtime&#xff0c;然后Next&#xff1a; Node.js runtime &#xff1a;表示运行环境 npm package mana…...