JVM 方法区

news2024/11/17 11:23:16

栈、堆、方法区的交互关系

线程共享角度:

 新建对象分配:

方法区的理解

  • 方法区(Method Area) 与 Java 堆一样,是各个线程共享的内存区域
  • 方法区在 JVM 启动的时候被创建,并且它的实际物理内存空间中和 Java 堆区一样都可以不连续的
  • 方法区的大小,跟堆空间一样,可以选择固定大小或者可扩展
  • 方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机同样会抛出内存溢出的错误: java.lang.OutOfMemoryError: PermGen space (jdk7 及 jdk7之前) 或者 java.lang.OutOfMemoryError: Metaspace (jdk7之后)
  • 关闭 JVM 救护释放这个区域的内存
  • 元空间和永久代最大区别: 元空间不在虚拟机设置的内存中,而是使用本地内存

设置方法区大小与OOM

版本参数说明
jdk7 及 以前-XX:PermSize设置永久代初始化分配空间,默认值是 20.75M
-XX:MaxPermSize设定永久代最大可分配空间。32位机器默认是64M,64位机器模式是82M
jdk8 及 以后-XX:MetaspaceSize设置元空间初始化分配空间,默认值是 21M,避免 Full GC 频繁,尽量设置大一些
-XX:MaxMetaspaceSize默认是-1,即没有限制

 OOM 示例代码:

import com.sun.xml.internal.ws.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;

/**
 * jdk8: -XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10
 */
public class OOMMethodTest extends ClassLoader{
    public static void main(String[] args) {
        int j = 0;
        try {
            OOMMethodTest oomMethodTest = new OOMMethodTest();
            for (int i = 0; i < 10000; i++) {
                // 创建 ClassWriter 对象, 用于生成类的二进制字节码
                ClassWriter classWriter = new ClassWriter(0);

                // 指明版本号, 修饰符,类名,包名,父类,接口
                classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Class" + i, null, "java/lang/Object", null);

                // 返回 byte[]
                byte[] code = classWriter.toByteArray();
                oomMethodTest.defineClass("Class" + i, code, 0, code.length); // class 对象
                j++;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            System.out.println(j);
        }
    }
}

如何解决 OOM:

  • 首先通过内存映射分析工具 对 dump 出来的堆转储快照进行分析,重点是确认内存中的对象是否是必要的,也就是要先分清楚到底是出现了内存泄漏(Memory )
  • 如果是内存泄漏,可进一步通过工具查看泄漏对象到 GC Roots 的引用链。于是就能找到泄漏对象是通过怎样的路径与 GC Roots 相关联并导致垃圾收集器无法自动回收他们的。掌握了泄漏对象的类型信息,以及 GC Roots 引用链的信息,就可以比较准确定位出泄露代码的位置
  • 如果不存在内存泄漏,那就应该检查虚拟机的堆参数(-Xmx 与 -Xms), 与机器物理内存对比看是否还需要调大,从代码上检查是否存在某些对象生命周期过长、持有状态时间过长的情况,尝试减少程序运行期的内存消耗

方法区的内部结构

它用于存储已被虚拟机加载的类型信息(域信息,方法信息)、常量、静态变量、及时编译期编译后的代码缓存等。

实例代码:

import java.io.Serializable;

public class MethodInnerStrucTest extends Object implements Comparable<String>, Serializable {
    // 属性
    private int num = 10;
    private static String str = "测试方法的内部结构";

    // 构造器
    // 方法
    public void test1(){
        int count = 20;
        System.out.println("count=" + count);
    }

    public static int test2(int cal) {
        int result = 0;
        try{
            int value = 30;
            result = value / cal;
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }
    @Override
    public int compareTo(String o) {
        return 0;
    }
}

执行 javap -v -p:

Classfile /E:/workspace/bxtech/bxtech/bxtech-test/target/classes/com/bxtech/jvm/MethodInnerStrucTest.class
  Last modified 2023-5-12; size 1620 bytes
  MD5 checksum 9efe01e181b9d9d60d967d9e19492a26
  Compiled from "MethodInnerStrucTest.java"
// 类型信息
public class com.bxtech.jvm.MethodInnerStrucTest extends java.lang.Object implements java.lang.Comparable<java.lang.String>, java.io.Serializable
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #18.#52        // java/lang/Object."<init>":()V
   #2 = Fieldref           #17.#53        // com/bxtech/jvm/MethodInnerStrucTest.num:I
   #3 = Fieldref           #54.#55        // java/lang/System.out:Ljava/io/PrintStream;
   #4 = Class              #56            // java/lang/StringBuilder
   #5 = Methodref          #4.#52         // java/lang/StringBuilder."<init>":()V
   #6 = String             #57            // count=
   #7 = Methodref          #4.#58         // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   #8 = Methodref          #4.#59         // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   #9 = Methodref          #4.#60         // java/lang/StringBuilder.toString:()Ljava/lang/String;
  #10 = Methodref          #61.#62        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #11 = Class              #63            // java/lang/Exception
  #12 = Methodref          #11.#64        // java/lang/Exception.printStackTrace:()V
  #13 = Class              #65            // java/lang/String
  #14 = Methodref          #17.#66        // com/bxtech/jvm/MethodInnerStrucTest.compareTo:(Ljava/lang/String;)I
  #15 = String             #67            // 测试方法的内部结构
  #16 = Fieldref           #17.#68        // com/bxtech/jvm/MethodInnerStrucTest.str:Ljava/lang/String;
  #17 = Class              #69            // com/bxtech/jvm/MethodInnerStrucTest
  #18 = Class              #70            // java/lang/Object
  #19 = Class              #71            // java/lang/Comparable
  #20 = Class              #72            // java/io/Serializable
  #21 = Utf8               num
  #22 = Utf8               I
  #23 = Utf8               str
  #24 = Utf8               Ljava/lang/String;
  #25 = Utf8               <init>
  #26 = Utf8               ()V
  #27 = Utf8               Code
  #28 = Utf8               LineNumberTable
  #29 = Utf8               LocalVariableTable
  #30 = Utf8               this
  #31 = Utf8               Lcom/bxtech/jvm/MethodInnerStrucTest;
  #32 = Utf8               test1
  #33 = Utf8               count
  #34 = Utf8               test2
  #35 = Utf8               (I)I
  #36 = Utf8               value
  #37 = Utf8               e
  #38 = Utf8               Ljava/lang/Exception;
  #39 = Utf8               cal
  #40 = Utf8               result
  #41 = Utf8               StackMapTable
  #42 = Class              #63            // java/lang/Exception
  #43 = Utf8               compareTo
  #44 = Utf8               (Ljava/lang/String;)I
  #45 = Utf8               o
  #46 = Utf8               (Ljava/lang/Object;)I
  #47 = Utf8               <clinit>
  #48 = Utf8               Signature
  #49 = Utf8               Ljava/lang/Object;Ljava/lang/Comparable<Ljava/lang/String;>;Ljava/io/Serializable;
  #50 = Utf8               SourceFile
  #51 = Utf8               MethodInnerStrucTest.java
  #52 = NameAndType        #25:#26        // "<init>":()V
  #53 = NameAndType        #21:#22        // num:I
  #54 = Class              #73            // java/lang/System
  #55 = NameAndType        #74:#75        // out:Ljava/io/PrintStream;
  #56 = Utf8               java/lang/StringBuilder
  #57 = Utf8               count=
  #58 = NameAndType        #76:#77        // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #59 = NameAndType        #76:#78        // append:(I)Ljava/lang/StringBuilder;
  #60 = NameAndType        #79:#80        // toString:()Ljava/lang/String;
  #61 = Class              #81            // java/io/PrintStream
  #62 = NameAndType        #82:#83        // println:(Ljava/lang/String;)V
  #63 = Utf8               java/lang/Exception
  #64 = NameAndType        #84:#26        // printStackTrace:()V
  #65 = Utf8               java/lang/String
  #66 = NameAndType        #43:#44        // compareTo:(Ljava/lang/String;)I
  #67 = Utf8               测试方法的内部结构
  #68 = NameAndType        #23:#24        // str:Ljava/lang/String;
  #69 = Utf8               com/bxtech/jvm/MethodInnerStrucTest
  #70 = Utf8               java/lang/Object
  #71 = Utf8               java/lang/Comparable
  #72 = Utf8               java/io/Serializable
  #73 = Utf8               java/lang/System
  #74 = Utf8               out
  #75 = Utf8               Ljava/io/PrintStream;
  #76 = Utf8               append
  #77 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #78 = Utf8               (I)Ljava/lang/StringBuilder;
  #79 = Utf8               toString
  #80 = Utf8               ()Ljava/lang/String;
  #81 = Utf8               java/io/PrintStream
  #82 = Utf8               println
  #83 = Utf8               (Ljava/lang/String;)V
  #84 = Utf8               printStackTrace
{
  // 域信息
  private int num;
    descriptor: I
    flags: ACC_PRIVATE

  private static java.lang.String str;
    descriptor: Ljava/lang/String;
    flags: ACC_PRIVATE, ACC_STATIC
  
// 构造器 方法
  public com.bxtech.jvm.MethodInnerStrucTest();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: bipush        10
         7: putfield      #2                  // Field num:I
        10: return
      LineNumberTable:
        line 5: 0
        line 7: 4
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      11     0  this   Lcom/bxtech/jvm/MethodInnerStrucTest;
  // 方法信息
  public void test1();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=2, args_size=1
         0: bipush        20
         2: istore_1
         3: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         6: new           #4                  // class java/lang/StringBuilder
         9: dup
        10: invokespecial #5                  // Method java/lang/StringBuilder."<init>":()V
        13: ldc           #6                  // String count=
        15: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        18: iload_1
        19: invokevirtual #8                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
        22: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        25: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        28: return
      LineNumberTable:
        line 13: 0
        line 14: 3
        line 15: 28
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      29     0  this   Lcom/bxtech/jvm/MethodInnerStrucTest;
            3      26     1 count   I

  public static int test2(int);
    descriptor: (I)I
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=1
         0: iconst_0
         1: istore_1
         2: bipush        30
         4: istore_2
         5: iload_2
         6: iload_0
         7: idiv
         8: istore_1
         9: goto          17
        12: astore_2
        13: aload_2
        14: invokevirtual #12                 // Method java/lang/Exception.printStackTrace:()V
        17: iload_1
        18: ireturn
      Exception table:
         from    to  target type
             2     9    12   Class java/lang/Exception
      LineNumberTable:
        line 18: 0
        line 20: 2
        line 21: 5
        line 24: 9
        line 22: 12
        line 23: 13
        line 25: 17
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            5       4     2 value   I
           13       4     2     e   Ljava/lang/Exception;
            0      19     0   cal   I
            2      17     1 result   I
      StackMapTable: number_of_entries = 2
        frame_type = 255 /* full_frame */
          offset_delta = 12
          locals = [ int, int ]
          stack = [ class java/lang/Exception ]
        frame_type = 4 /* same */

  public int compareTo(java.lang.String);
    descriptor: (Ljava/lang/String;)I
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=2, args_size=2
         0: iconst_0
         1: ireturn
      LineNumberTable:
        line 29: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       2     0  this   Lcom/bxtech/jvm/MethodInnerStrucTest;
            0       2     1     o   Ljava/lang/String;

  public int compareTo(java.lang.Object);
    descriptor: (Ljava/lang/Object;)I
    flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: checkcast     #13                 // class java/lang/String
         5: invokevirtual #14                 // Method compareTo:(Ljava/lang/String;)I
         8: ireturn
      LineNumberTable:
         5: return
      LineNumberTable:
        line 8: 0
}
Signature: #49                          // Ljava/lang/Object;Ljava/lang/Comparable<Ljava/lang/String;>;Ljava/io/Serializable;

类型信息:

对每个加载的类型(类 class、接口 interface、枚举 enum、注解 annotation),JVM 必须在方法区中存储一下类型信息

  • 这个类完整有效名称(全名=包名.类名)
  • 这个类型直接父类的完整有效名(对于 interface 或是 java.lang.Object, 都没有父类)
  • 这个类型修饰符(public, abstract, final 的某个子集)
  • 这个类型直接接口的一个有序列表

域(Field)信息:

  • JVM 必须在方法区中保存类型的所有域的相关信息以及域的声明顺序
  • 域的相关信息包括: 域名称、域类型、域修饰符 (public, private, protected, static, final, volatile, transient 的某个子集)

方法(Method) 信息:

JVM 必须保存所有方法的以下信息,同域信息一样包括声明顺序:

  • 方法名称
  • 方法的返回类型
  • 方法参数的数量和类型(按顺序)
  • 方法的修饰符(public, private, protected, static, final, synchronized, native, abstract 的一个子集)
  • 方法的字节码(bytecodes)、操作数栈、局部变量表及大小(abstract 和 native 方法除外)
  • 异常表(abstract 和 native 方法除外),每个异常处理的开始位置、结束位置、代码处理在程序计数器中的偏移地址、被捕获的异常类的常量池索引

non-final 的类变量:

  • 静态变量和类关联在一起,随着类的加载而加载,它们成为类数据在逻辑上的一部分
  • 类变量被类的所有实例共享,即没有类实例时你也可以访问它
  • 被声明为 final 的类变量的处理方法则不同,每个全局变量在编译的时候就会被分配了

常量池:

一个有效的字节码文件中除了包含类的版本信息、字段、方法以及接口等描述信息外,还包含一项信息那就是常量池表(Constant Pool Table), 包括各种字面量和对类型、域和方法的符号引用。

为什么需要常量池:

一个 Java 源文件中的类、接口,编译后产生一个字节码文件。而 Java 中的字节码需要数据支持,通常这种数量会很大以至于不能直接存到字节码里,换另一种方式,可以存到常量池,这个字节码包含了指向常量池的引用。在动态链接的时候会用到运行时常量池

运行时常量池:

  • 运行时常量池(Runtime Constant Pool) 是方法区的一部分
  • 常量池(Constant Pool Table) 是 Class 文件的一部分,用于存放编译期生成的各种字面量与符号引用,这部分内容在类加载后存放到方法区的运行时常量池中
  • 运行时常量池,在加载类和接口到虚拟机后,就会创建对应的运行时常量池
  • JVM 为每个已加载的类型(类和接口)都维护一个常量池。池中的数据项像数组项一样,通过索引访问
  • 运行时常量池中包含各种不同的变量,包括编译期就已经明确的数值字面量,也包括到运行期解析后才能够获得的方法或者字段引用。此时不再是常量池中的符号地址了,这里换为真实地址。运行时常量池,相对于 Class 文件常量池的另一个重要特征: 具备动态性
  • 运行时常量池类似于传统编程语言中的符号表(symbol talbe), 但是它所包含的数据却比符号表要更加丰富一些
  • 当创建类或接口的运行时常量池时,如果构造运行时常量池所需的内存空间超过了方法区所能提供的最大值,则 JVM 会抛出 OutOfMemoryError 异常

方法区的演进细节

  • 只有 HotSpot 才有永久代。 BEA JRockit、IBM J9 是不存在永久代的概念
  • HotSpot中的方法区的变化:
版本说明
jdk1.6 及以前有永久代(permanent generation), 静态变量存放在永久代上
jdk1.7有永久代, 但已经逐步 “去永久代”, 字符串常量池、静态变量移除、保存在堆中
jdk1.8 之后无永久代,类型信息、字段、方法、常量保存在本地内存的元空间,但字符串常量池、静态变量仍在堆

永久代为什么要被元空间替换:

  • 为永久代设置空间大小是很难确定的
  • 对永久代进行调优是很困难的

StringTable 为什么要调整位置:

因为永久代垃圾回收效率很低,在 Full GC 的时候才会触发,而 Full GC 是老年代的空间不足,永久代不足时才会触发。这就导致 StringTable 回收效率不高。而我们开发中会有大量字符串被创建,回收效率低,导致永久代内存不足。放在堆里,能及时回收内存

方法区的垃圾回收

方法区的垃圾收集主要回收两部分内容: 常量池中废弃的常量和不再使用的类型

常量池回收:

  • 主要存放两大类常量:字面量和符号引用,字面量比较接近 常量概念,比如文本字符串、被声明为 final 的常量值。而符号引用包括: 类和接口的全限定义、字段的名称和描述符、方法的名称和描述符。
  • 只要常量池中的常量没有被任何地方引用,就可以被回收

类的垃圾回收:

  • 该类所有的实例都已经回收了
  • 加载该类的类加载器已经被回收了
  • 该类对应的 java.lang.Class 对象没有任何地方引用,无法在任何地方通过反射访问该类的方法

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

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

相关文章

08-02 底层数据设计策略 - 分库分表,热点热数据隔离

关系型数据库的伸缩 读写分离 缓存和搜索引擎本质上也是一种读写分离 商品是典型的读多写少的场景 分库分表 略知一二 分表 分库 业务量大的数据基本都得使用分库分表&#xff0c;不然单表的数据量大之后&#xff0c;性能太差 数据迁移和扩容 成倍扩容 直接…

centos搭建redis并配置redis主从复制

一、gcc环境搭建 1.检查是否有gcc环境&#xff1a; gcc -v#运行命令 gcc -v #如果显示:-bash: gcc: command not found # 表示没有该环境 #如果显示下文&#xff0c;代表有gcc环境 Using built-in specs. COLLECT_GCCgcc COLLECT_LTO_WRAPPER/usr/libexec/gcc/x86_64-redha…

Java中ArrayList的三种构造方法

ArrayList的构造方法 //三种构造方法 ArrayList()// 无参构造 ArrayList(Collection<? extends E> c) //利用其他 Collection 构建 ArrayList ArrayList(int initialCapacity) //指定顺序表初始容量1.无参构造方法 其中elementData是一个成员数组&#xff0c;类型是Ob…

什么是敏捷开发?敏捷开发流程的8个步骤

文章目录 一、什么是敏捷开发&#xff1f;二、敏捷开发模式的分类三、SCRUM 的工作流程四、敏捷开发流程的8个步骤包括&#xff1a;五、敏捷开发模型 一、什么是敏捷开发&#xff1f; 敏捷开发&#xff08;Agile&#xff09;是一种以人为核心、迭代、循序渐进的开发方法。 在…

phpstorm 配置xdebug

目录 配置全局环境 phpstorm 项目xdebug配置 额外补充&#xff1a; 配置全局环境 本地运行命令 php -v, 看是否有Xdebug相关的信息若没有&#xff0c;安装xdebug&#xff0c;以下是mac相关方式&#xff1a; pecl search xdebug 查询&#xff0c;找到之后用 pecl install xdebug…

【企业信息化】第4集 免费开源ERP: Odoo 16 Rental租赁管理系统

文章目录 前言一、概览二、使用功能1.提高出租效率2.产品 & 价格3.销售订单4.跟进5.报告6.集成 三、总结 前言 唯一可以满足您所有需求的租赁软件 从时间安排到开具发票。 您的所有租赁流程都集中在一处。 一、概览 从租金报价到发票 从一处管理所有事务。 从一个视图创建您…

强力推荐,两款Excel插件,极致好用,让你秒变高手

Excel是我们日常生活工作中应用最多、业界最标准的表格软件。 由于Excel的用户数量非常庞大&#xff0c;在社区支持方面非常丰富&#xff0c;用户可以轻松地找到各种教程和解决方案。 虽然Excel很功能已经成熟&#xff0c;但自身也存在一定的局限性&#xff0c;很多用户在网上…

git仓库新建项目第一次推送代码流程记录

git仓库新建项目第一次推送代码流程记录 换了个坑之后,公司改用SVN管理代码,隔了好长时间没用git,突然又捡起来,有点懵逼,简单记录一下。 电脑安装git之后,在项目父文件夹处,右键选择“Git Bash Here”打开git小黑窗。 在gti后台创建新项目目录之后,如果是空的项目,…

洛谷P1909-买铅笔

洛谷P1909-买铅笔 大家来看一道简单的题&#xff0c;第一次写的时候我过了一半&#xff0c;看了半天自己的代码&#xff0c;还感觉没问题&#xff0c;还是学艺不精啊 先看题目 #include <iostream> using namespace std; int n;//要买的铅笔数 int n1,m1; int n2,m2; i…

(数字图像处理MATLAB+Python)第八章图像复原-第一节:图像复原概述

文章目录 一&#xff1a;图像复原概述二&#xff1a;图像退化模型&#xff08;1&#xff09;连续退化模型&#xff08;2&#xff09;离散退化模型 三&#xff1a;图像退化函数的估计&#xff08;1&#xff09;基于模型的估计法&#xff08;2&#xff09;运动模糊退化估计 一&am…

(双指针)leetcode11. 盛最多水的容器

文章目录 一、题目1、题目描述2、基础框架3、原题链接 二、解题报告1、思路分析2、时间复杂度3、代码详解 三、本题小知识 一、题目 1、题目描述 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中…

win10系统ssh连接阿里云linux服务器并传输文件教程

前言 因为业务需要&#xff0c;最近搞了一台linux的阿里云服务器&#xff0c;现在要连接阿里云服务器。 之前没有玩过这种云服务器&#xff0c;两眼一抹黑&#xff0c;在网上搜索资料也比较少&#xff0c;所以写篇博客记录一下连接的步骤&#xff0c;以防止忘记。 SSH命令行…

如何使用Nodejs搭建HTTP服务,实现公网远程访问「内网穿透」

文章目录 前言1.安装Node.js环境2.创建node.js服务3. 访问node.js 服务4.内网穿透4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5.固定公网地址 转载自内网穿透工具的文章&#xff1a;使用Nodejs搭建HTTP服务&#xff0c;并实现公网远程访问「内网穿透」 前言 Node.js…

Linux 之 yum使用(yum 命令使用讲解)

一、yum介绍 Yum(全称为 Yellow dogUpdater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器。基于RPM包管理&#xff0c;能够从指定的服务器自动下载RPM包并且安装&#xff0c;可以自动处理依赖性关系&#xff0c;并且一次安装所有依赖的软件包&#x…

优思学院|何时应该使用8D方法?

8D&#xff08;Eight Disciplines&#xff09;过程是一种用于问题解决和改进的方法&#xff0c;其包含8个步骤。 D0是准备8D过程的阶段&#xff0c;其作用在于帮助我们判断是否需要使用8D来解决问题。如果问题的根本原因明显&#xff0c;可以通过直接采取措施来解决异常&#…

基于turtlebot3实现SLAM建图及自主导航仿真

一、turtlebot3依赖安装 1、安装turtlebot3 sudo apt-get install ros-noetic-turtlebot3-* //安装gmapping建图算法依赖 apt-get install ros-noetic-gmapping //安装dwa局部路径规划算法 apt-get install ros-noetic-dwa-local-planner 2、安装键盘依赖 sudo apt-get insta…

别再手动一个个添加了。使用While循环控制器轻松遍历获取文件参数

目录 测试环境 应用 实现单线程在单次迭代内遍历获取文件参数 软件测试学习心得分享 一、最后这里详细的给大家说下&#xff0c;对于0基础的朋友&#xff0c;应该怎么去学习软件测试。 二、自学软件测试需要多久&#xff1f;&#xff08;从真正的零基础到找到软件测试的工…

设计原则之【接口隔离原则】,我只做我能做的事

文章目录 一、什么是接口隔离原则二、实例三、总结接口隔离原则与单一职责原则的区别 一、什么是接口隔离原则 接口隔离原则&#xff08;Interface Segregation Principle, ISP&#xff09;是指用多个专门的接口&#xff0c;而不使用单一的总接口&#xff0c;客户端不应该依赖…

OpenDDS安装环境构建+Demo实践(自己动手写一个)

此文用于辅助构建类似于OpenDDS\DevGuideExamples\DCPS\Messenger的Demo示例 OpenDDS安装环境构建Demo实践&#xff08;自己动手写一个&#xff09; 本文相关参考资料OpenDDS安装环境构建参考博客 Demo上手实践&#xff08;依赖于Windows下的OpenDDS环境&#xff09;OpenDDS安…

Android中常见的内存优化及内存泄露场景

避免内存泄露的关键是及时释放不再需要的资源,特别是生命周期较长的资源。在Activity和Fragment的生命周期方法中释放这些资源,如onDestroy()方法中释放线程、集合等引用,避免这些资源的生命周期过长导致内存泄露。 Android内存优化主要有以下几个方面: 合理设置应用的minSdk…