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

JVM运行时数据区域、对象内存分配、内存溢出异常总结

深入理解java虚拟机第二章

    • 二、运行时数据区域
      • 2.2.1 程序计数器
      • 2.2.2 Java虚拟机栈
      • 2.2.3 本地方法栈
      • 2.2.4 Java堆
      • 2.2.5 方法区
      • 2.2.6 运行时常量池
      • 2.2.7 直接内存
    • 三、HotSpot虚拟机对象解密
      • 2.3.1 对象的创建
        • 对象如何分配内存?
        • 对象的创建如何处理并发问题?
      • 2.3.2 对象的内存布局
      • 2.3.3 对象的访问定位
    • 四、实战:OutOfMemoryError异常
      • 2.4.1 Java堆溢出
      • 2.4.2 虚拟机栈和本地方法栈溢出
      • 2.4.3 方法区和运行时常量池溢出
      • 2.4.4 本机直接内存溢出

参考资料:《深入理解Java虚拟机》

二、运行时数据区域

在这里插入图片描述

2.2.1 程序计数器

程序计数器记录了当前线程所运行的字节码,以及之后要运行的字节码。在jvm中,字节码解释器通过改变程序计数器的值来执行下一条字节码命令。

jvm是通过线程轮流切换达到多线程效果的

2.2.2 Java虚拟机栈

方法被执行时,java虚拟机会同步创建一个栈帧。栈帧包括局部变量表、操作数栈、动态链接、方法出口等信息

每一个方法被执行直到被执行完毕的过程,对应着一个栈帧在虚拟机中入栈到出栈的过程

局部变量表存放了基本数据类型以及对象引用,所以当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小

  • StackOverflowError:线程请求的栈深度大于虚拟机所允许的栈深度,就会抛出此异常

  • OutofMemoryError:虚拟机栈容量动态扩容申请内存时无法申请到适当的内存,就会抛出此异常。由于HotSpot无法动态扩容,所以基本上不会抛出OOM。但如果一开始申请空间就失败,也会抛出OutofMemoryError

2.2.3 本地方法栈

本地方法栈是为虚拟机执行本地方法服务的

HotSpot虚拟机将本地方法栈与虚拟机栈合二为一

2.2.4 Java堆

Java堆是被所有线程共享的一块区域,在虚拟机启动时创建。

The heap is the runtime data area from which memory for all class instances and arrays is allocated

堆是为所有类实例(对象)和数组分配空间的一块运行时内存。

此处的“所有”不是那么严谨的,因为由于栈上分配、标量替换等优化手段已经导致一些微妙的变化悄然发生,所以Java对象实例都分配在堆上也渐渐变得不那么绝对了。(栈上分配即有一些对象没有必要存储在堆内存中,将其存储在栈中的内存优化方式)

Java堆是垃圾收集器管理的内存区域,现代的垃圾收集器大部分是采用分代收集理论设计的(但到了今天,HotSpot里面也出现了不采用分代设计的新垃圾收集器)

Java堆既可以被实现成固定大小的,也可以是可扩展的。如果Java堆中没有内存完成实例分配,并且堆也无法扩展时,Java虚拟机会抛出OutOfMemoryError异常

2.2.5 方法区

方法区与Java堆一样,是各个线程共享的内存区域,它用于存储被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。但是现在来看,这种设计导致了Java应用更容易遇到内存溢出的问题,所以到了JDk7的HotSpot,已经把原本放在永久代的字符串常量池、静态变量等移植到Java堆中。到了JDK8,完全废弃了永久代的概念,改用在本地内存中实现的元空间来代替,把JDK7中永久代还剩余的内容(主要是类型信息)全部移到元空间中。

  • 方法区主要存放的是Class信息,而堆中主要存放的是实例化的对象
  • 多个线程同时加载一个类时,只能有一个线程加载该类,其他线程要等该线程加载完毕之后直接使用该类,类只能加载一次
  • 方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类导致方法区溢出,虚拟机同样会抛出OOM

2.2.6 运行时常量池

运行时常量池是方法区的一部分,Class文件中有一项信息是常量池表,用于存放编译器生成的各种字面量和符号引用,这部分内容在类加载后存放到方法区的运行时常量池中。

一般来说,除了保存Class文件中描述的符号引用外,还会把有符号引用翻译出来的直接引用也存储在运行时常量池中。

2.2.7 直接内存

直接内存并不是虚拟机运行时数据区的一部分,但是这部分内存被频繁地使用,而且也可能导致OutOfMemoryError异常出现。

简单来讲就是使用Java堆里面的DirectByteBuffer对象作为一块堆外内存的引用对堆外内存进行操作,这样可以在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。

三、HotSpot虚拟机对象解密

本节将深入探讨HotSpot虚拟机在Java堆中对象分配、布局和访问的全过程

2.3.1 对象的创建

  1. 检查这个指令的参数是否能在常量池中定位到一个类的符号引用
  2. 检查这个符号引用代表的类是否已经被加载
  3. 为新生对象分配内存—>将分配到的内存空间(不包括对象头)
  4. 对对象进行必要的设置,如对象所属类、如何找到类的元数据信息、对象的hash码、对象的GC分代年龄信息,存放在对象头中
  5. 执行构造函数对对象的实例字段赋值
对象如何分配内存?
  • 指针碰撞

假设Java堆中的内存是绝对规整的,所有被使用过的内存都被放在一边,空闲的内存都被放在另一边。中间放着一个指针作为分界点的治时期,分配内存时仅仅把指针向空闲空间方向移动一段对象大小的距离,这种方式就称为“指针碰撞”。

  • 空闲列表

假设Java堆内存并不规整,虚拟机就必须维护一个列表,记录哪块内存是可用的,再分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录。

  • 选择

选择哪种对象根据Java堆是否规整决定,Java堆是否规整由所采用的垃圾收集器是否带有空间压缩整理的能力决定。当Serial、ParNew等带压缩整理过程的收集器时,系统采用的分配算法是指针碰撞,既简单又高效。当使用CMS这种基于清除算法的收集器时,理论上就只能采用较为复杂的空闲列表来分配内存。

对象的创建如何处理并发问题?
  • 对分配内存空间的动作进行同步处理

虚拟机采用CAS配上失败重试的方式保证更新操作的原子性

  • 分配缓冲

为每个线程在Java堆中预先分配一小块内存,成为本地线程分配缓冲,哪个线程要分配内存,就在哪个线程的本地缓冲区中分配,只有本地缓冲区用完了,分配新的缓冲区时才需要加锁。

2.3.2 对象的内存布局

对象在堆内存中的存储布局可以划分为三个部分:对象头、实例数据、对齐填充

  • 对象头(Mark Word)

对象需要存储的运行时数据很多,已经超出了32、64位Bitmap结构所能记录的最大限度,但对象头里的信息是与对象自身定义的数据无关的额外存储成本,考虑到虚拟机的空间效率,Mark Word被设计成一个有着动态定义的数据结构,以便在极小的空间内存储尽量多的数据,根据对象的状态复用自己的存储空间

HotSpot虚拟机对象对象头部分包括两类信息

​ 1、对象自身运行时数据:哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳

​ 2、类型指针,即对象指向它的类型元数据的指针,Java虚拟机通过这个指针来确定该对象是哪个类的实例

​ 3、如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据

  • 实例数据

HotSpot虚拟机默认的分配顺序为longs/doubles、ints、shorts/chars、bytes/booleans、oops(对象指针 Ordinary Object Pointers)

JVM重新分配字段的排列顺序受-XX:FieldsAllocationStyle参数的影响,默认值为1,实例字段的重新分配策略遵循以下规则:

  • 如果一个字段占用X个字节,那么这个字段的偏移量OFFSET需要对齐至NX

偏移量是指字段的内存地址与Java对象的起始内存地址之间的差值。比如long类型的字段,它内存占用8个字节,那么它的OFFSET应该是8的倍数8N。不足8N的需要填充字节。

  • 在开启了压缩指针的64位JVM中,Java类中的第一个字段的OFFSET需要对齐至4N,在关闭压缩指针的情况下类中第一个字段的OFFSET需要对齐至8N。

JVM默认分配字段的顺序为:long / double,int / float,short / char,byte / boolean,oops(Ordianry Object Point 引用类型指针),并且父类中定义的实例变量会出现在子类实例变量之前。当设置JVM参数-XX +CompactFields 时(默认),占用内存小于long / double 的字段会允许被插入到对象中第一个 long / double字段之前的间隙中,以避免不必要的内存填充。

  • 对齐填充

占位符

2.3.3 对象的访问定位

主流的访问方式主要有使用句柄和直接指针两种:

  • 句柄

如果使用句柄访问的话,Java堆中可能会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,句柄中包含了对象实例数据与类型数据各自具体的地址信息

在这里插入图片描述

  • 直接指针

reference中存储对象地址,对象中存储类型地址,不需要多一次间接的访问开销

在这里插入图片描述

使用直接指针可以节省一次指针定位的时间开销,对于HotSpot而言,它主要使用第二种方式进行对象访问

四、实战:OutOfMemoryError异常

2.4.1 Java堆溢出

Java堆内存溢出异常测试:

VM Options: -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError

最小/大堆容量20mb 导出第一次堆转存储快照文件

public class Main{static class OOMObject{int anInt;public OOMObject(int anInt){this.anInt = anInt;}}public static void main(String[]    args){List<OOMObject> list = new ArrayList<>();while (true){list.add(new OOMObject(1));}}
}java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid17568.hprof ...
Heap dump file created [31422169 bytes in 0.076 secs]、
堆转储快照文件(查看内存的分布情况)
Exception in thread "main" java.lang.OutOfMemoryError: Java heap spaceat java.util.Arrays.copyOf(Arrays.java:3210)at java.util.Arrays.copyOf(Arrays.java:3181)at java.util.ArrayList.grow(ArrayList.java:267)at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:241)at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:233)at java.util.ArrayList.add(ArrayList.java:464)at 算法复杂度.Main.main(Main.java:18)

2.4.2 虚拟机栈和本地方法栈溢出

两种栈溢出:

  1. 如果线程请求的栈深度大于虚拟机所允许的最大深度,抛出StackOverflowError异常
  2. 如果虚拟机的占内存允许动态扩展,当扩展栈容量无法申请到足够的内存时,抛出OutOfMemoryError异常

虚拟机栈和本地方法栈测试:

参数:-Xss128k

public class Main{private int stackLength = 1;public void stackLeak(){stackLength++;stackLeak();}public static void main(String[]    args){Main main = new Main();try {main.stackLeak();}catch (Throwable e){System.out.println("stack length:" + main.stackLength);throw e;}}
}stack length:983
Exception in thread "main" java.lang.StackOverflowError

虚拟机栈和本地方法栈测试:

public class Main{private static int stackLength = 0;public static void test() {long unused1, unused2, unused3, unused4, unused5, unused6, unused7, unused8, unused9,unused10, unused11, unused12, unused13, unused14, unused15, unused16, unused17,unused18, unused19, unused20, unused21, unused22, unused23, unused24, unused25,unused26, unused27, unused28, unused29, unused30, unused31, unused32, unused33,unused34, unused35, unused36, unused37, unused38, unused39, unused40, unused41,unused42, unused43, unused44, unused45, unused46, unused47, unused48, unused49,unused50, unused51, unused52, unused53, unused54, unused55, unused56, unused57,unused58, unused59, unused60, unused61, unused62, unused63, unused64, unused65,unused66, unused67, unused68, unused69, unused70, unused71, unused72, unused73,unused74, unused75, unused76, unused77, unused78, unused79, unused80, unused81,unused82, unused83, unused84, unused85, unused86, unused87, unused88, unused89,unused90, unused91, unused92, unused93, unused94, unused95, unused96, unused97,unused98, unused99, unused100;stackLength++;test();unused1 = unused2 = unused3 = unused4 = unused5 = unused6 = unused7 = unused8 = unused9 = unused10 = unused11 = unused12 = unused13 = unused14 = unused15 = unused16 = unused17 = unused18 = unused19 = unused20 = unused21 = unused22 = unused23 = unused24 = unused25 = unused26 = unused27 = unused28 = unused29 = unused30 = unused31 = unused32 = unused33 = unused34 = unused35 = unused36 = unused37 = unused38 = unused39 = unused40 = unused41 = unused42 = unused43 = unused44 = unused45 = unused46 = unused47 = unused48 = unused49 = unused50 = unused51 = unused52 = unused53 = unused54 = unused55 = unused56 = unused57 = unused58 = unused59 = unused60 = unused61 = unused62 = unused63 = unused64 = unused65 = unused66 = unused67 = unused68 = unused69 = unused70 = unused71 = unused72 = unused73 = unused74 = unused75 = unused76 = unused77 = unused78 = unused79 = unused80 = unused81 = unused82 = unused83 = unused84 = unused85 = unused86 = unused87 = unused88 = unused89 = unused90 = unused91 = unused92 = unused93 = unused94 = unused95 = unused96 = unused97 = unused98 = unused99 = unused100 = 0;}public static void main(String[] args) {try {test();} catch (Error e) {System.out.println("stack length:" + stackLength);throw e;}}
}stack length:52
Exception in thread "main" java.lang.StackOverflowError

结果:无论是由于栈帧太大还是虚拟机栈容量太小,当新的栈帧内存无法分配的时候,HotSpot虚拟机抛出的都是StackOverflowError异常。

2.4.3 方法区和运行时常量池溢出

运行时常量池导致的内存溢出异常:

public class RuntimeConstantPollOOM{public static void main(String[] args){Set<String> set = new HashSet<String>();short i = 0;while(true){set.add(String.valueOf(i++).intern());}}
}Exception in thread "main" java.lang.OutOfMemoryError: PermGen space

此方法使用JDK6运行,原因是在JDK7以后,原本存放在永久代的字符串常量池被移到Java堆中,所以在JDK7及以上版本,限制方法区的容量对测试用例来说是毫无意义的

String.intern()返回引用的测试:

public class RuntimeConstantPollOOM{public static void main(String[] args){String str1 = new StringBuilder("计算机").append("软件").toString();System.out.println(str1.intern() == str1);String str2 = new StringBuilder("ja").append("va").toString();System.out.println(str2.intern() == str2);}
}

JDK6中会得到两个false

JDK7中会得到一个true和一个false

原因是JDK6中intern()方法会把首次遇到的字符串实例复制到永久代的字符串常量池中存储,返回的也是永久代中的字符串实例的引用,但是由StringBuilder创建的字符串对象实例在Java堆上,所以必然不是同一个引用

在这里插入图片描述

JDK7的intern方法实现不需要拷贝字符串实例,既然字符串常量已经移到了Java堆中(到了JDk7的HotSpot,已经把原本放在永久代的字符串常量池、静态变量等移植到Java堆中),那只需要在常量池里记录一下首次出现的实例引用即可,因此intern返回的引用和StringBuilder创建的字符串实例就是同一个

借助CGLib使得方法区出现内存溢出异常:

public class JavaMethodAreaOOM{public static void main(String[] args){while(true){Enhancer enhancer = new Enhancer();enhancer.setSuperclass(OOMObject.class);enhancer.setUseCache(false);enhancer.setCallback(new MethodInterceptor(){public Object intercept(Object obj , Method method , Object[] args, MethodProxy proxy)throws Throwable{return proxy.invokeSuper(obj,args);}});enhancer.create();}}static class OOMObject{}
}java.lang.OutOfMemoryError:PermGen space

在JDK8以后,永久代便完全退出了历史舞台(到了JDK8,完全废弃了永久代的概念,改用在本地内存中实现的元空间来代替,把JDK7中永久代还剩余的内容(主要是类型信息)全部移到元空间中)。

2.4.4 本机直接内存溢出

使用unsafe分配本机内存

public class DirectMemoryOOM{private static final int _1MB = 1024 * 1024;public static void main(String[] args)throws Exception{Field unsafeField = Unsafe.class.getDeclaredFields()[0];unsafeField.setAccessible(true);Unsafe unsafe = (Unsafe) unsafeField.get(null);while(true){unsafe.allocateMemory(_1MB);}}
}Exception in thread "main" lava.lang.OutOfMemoryError

由直接内存导致的内存溢出,一个明显特征是Heap Dump文件中不会看见有什么明显的异常情况。

相关文章:

JVM运行时数据区域、对象内存分配、内存溢出异常总结

深入理解java虚拟机第二章 二、运行时数据区域2.2.1 程序计数器2.2.2 Java虚拟机栈2.2.3 本地方法栈2.2.4 Java堆2.2.5 方法区2.2.6 运行时常量池2.2.7 直接内存 三、HotSpot虚拟机对象解密2.3.1 对象的创建对象如何分配内存&#xff1f;对象的创建如何处理并发问题&#xff1f…...

【C++设计模式】单例模式singleton

C 设计模式–单例模式singleton 单例模式 单例模式是指确保一个类在任何情况下都绝对只有一个实例&#xff0c;并提供一个全局访问点。 优点&#xff1a;内存中只有一个实例&#xff0c;减少内存开销&#xff1b;避免对资源多重占用&#xff1b;设置全局访问点&#xff0c;严…...

CVPR 2023 精选论文学习笔记:Post-Training Quantization on Diffusion Models

基于MECE原则,我们给出以下四种分类依据: 1. 模型类型 生成模型用于生成与其训练数据相似的新数据。它们通常用于图像生成、文本生成和音乐生成等任务。语言模型用于理解和生成人类语言。它们通常用于机器翻译、聊天机器人和文本摘要等任务。其他模型用于各种任务,例如图像…...

Python基础语法之学习字符串快速格式化

Python基础语法之学习字符串快速格式化 一、代码二、效果 一、代码 # 通过f"{占位}"控制字符串快速格式化,不做精度控制 name "张三" age 13 money 12.5 text f"姓名是{name},年龄是{age},钱是{money}" print(text)二、效果 每一天都是一个…...

Ubuntu22.04 server版本关闭DHCP,手动设置ip

在Ubuntu 22.04 中&#xff0c;网络配置已迁移到 Netplan&#xff0c;因此可以使用 Netplan 配置文件来手动设置 IP 地址并关闭 DHCP。 以下是在 Ubuntu 22.04 上手动设置 IP 地址并禁用 DHCP 的步骤&#xff1a; 打开终端&#xff0c;使用 root 权限或 sudo 执行以下命令&…...

贪心算法(新坑)

贪心入门 概述&#xff1a; 贪心算法是一种在每一步选择中都采取当前最优解的策略&#xff0c;希望最终能够得到全局最优解的算法。简单来说&#xff0c;它会不断地做出局部最优的选择&#xff0c;相信通过这种选择最终能够达到全局最优。 举个例子来说明。假设你要从一个迷…...

C 语言头文件

C 语言头文件 头文件是扩展名为 .h 的文件&#xff0c;包含了 C 函数声明和宏定义&#xff0c;被多个源文件中引用共享。有两种类型的头文件&#xff1a;程序员编写的头文件和编译器自带的头文件。 在程序中要使用头文件&#xff0c;需要使用 C 预处理指令 #include 来引用它…...

MySQL中自增id用完怎么办?

MySQL中自增id用完怎么办&#xff1f; MySQL里有很多自增的id&#xff0c;每个自增id都是定义了初始值&#xff0c;然后不停地往上加步长。虽然自然数是没有上限的&#xff0c;但是在计算机里&#xff0c;只要定义了表示这个数的字节长度&#xff0c;那它就有上限。比如&#…...

C语言常见算法

算法&#xff08;Algorithm&#xff09;&#xff1a;计算机解题的基本思想方法和步骤。算法的描述&#xff1a;是对要解决一个问题或要完成一项任务所采取的方法和步骤的描述&#xff0c;包括需要什么数据&#xff08;输入什么数据、输出什么结果&#xff09;、采用什么结构、使…...

0-1背包的初始化问题

题目链接 这道题的状态转移方程比较易于确定。dp[i][j]表示能放前i个物品的情况下&#xff0c;容量为j时能放物品的数量&#xff08;这道题歌曲数量对应物品数量&#xff0c;容量对应时间&#xff09;。 技巧&#xff08;收获&#xff09; 二维dp数组可以视情况优化为一维dp数组…...

API之 要求接口上传pdf 以 合同PDF的二进制数据,multpart方式上传

实现 //时间戳13位毫秒private function getMillisecond() {list($s1,$s2) explode( ,microtime());return (float)sprintf(%.0f,(floatval($s1) floatval($s2)) * 1000);}// 组装参数private function gysscPost1($url,$data){// $data[timestamp] 1694402111964;$data[tim…...

C语言-求阶乘序列前N项和

本题要求编写程序&#xff0c;计算序列 1!2!3!⋯ 的前N项之和。 输入格式: 输入在一行中给出一个不超过12的正整数N。 输出格式: 在一行中输出整数结果。 输入样例: 5输出样例: 153 #include "stdio.h" int main(){int n;int sum 0;scanf("%d",&a…...

3:kotlin 逻辑控制(Control flow)

像其他语言一样&#xff0c;kotlin也有循环和逻辑控制 条件判断&#xff08;Conditional expressions&#xff09; kotlin使用if和when来进行条件判断 如果纠结选择if还是when&#xff0c;建议使用when&#xff0c;因为它更能提高程序的健壮性 if 普通写法 fun main() {val…...

Linux系统之一次性计划任务at命令的基本使用

Linux系统之一次性计划任务at命令的基本使用 一、at命令介绍二、at命令的使用帮助2.1 at命令的help帮助信息2.2 at命令的语法解释 三、at命令的日常使用3.1 立即执行一次性任务3.2 指定时间执行一次性任务3.3 查询计划任务3.4 其他指定时间用法3.5 删除已经设置的计划任务3.6 显…...

记录:Unity脚本的编写8.0

目录 需求分析设计GUI包含账号和密码输入栏&#xff0c;包括登录和注册按键添加背景音乐编写脚本控制音乐 退出按钮编写脚本 背景图片完整代码 一个小demo&#xff0c;登录和注册的实现&#xff08;包括GUI和数据库操控&#xff09; 需求分析 自行设计GUI&#xff0c;要求 1.包…...

OpenCV | 模版匹配

import cv2 #opencv读取的格式是BGR import numpy as np import matplotlib.pyplot as plt#Matplotlib是RGB %matplotlib inline 模版匹配 模版匹配和卷积原理很像&#xff0c;模版在原图像上从原点开始滑动&#xff0c;计算模版与&#xff08;图像被模版覆盖的地方&#xff…...

【算法刷题】Day7

文章目录 283. 移动零1089. 复写零 283. 移动零 原题链接 看到题目&#xff0c;首先看一下题干的要求&#xff0c;是在原数组内进行操作&#xff0c;平切保持非零元素的相对顺序 这个时候我们看到了示例一&#xff1a; [ 0, 1, 0, 3,12 ] 这个时候输出成为了 [ 1, 3, 12, 0, …...

前端 | iframe框架标签应用

文章目录 &#x1f4da;嵌入方式&#x1f4da;图表加载显示&#x1f4da;100%嵌入及滑动条问题&#x1f4da;加载动画保留 前情提要&#xff1a; 计划用iframe把画好的home1.html&#xff08;echarts各种图表组成的html数据大屏&#xff09;嵌入整合到index.html&#xff08;搭…...

linux -系统通用命令查询

有时候内网环境下&#xff0c;系统有些命令没有安装因此掌握一些通用的linux 命令也可以帮助我们解决一些问题查看 1.查看系统内核版本 uname -r2.查看系统版本 cat /etc/os-release3. 查看cpu 配置 lscpu4.查看内存信息 free [参数] 中各个数值的解释如下表 数值解释t…...

python炒股自动化(1),量化交易接口区别

要实现股票量化程序化自动化&#xff0c;就需要券商提供的API接口&#xff0c;重点是个人账户小散户可以申请开通&#xff0c;上手要简单&#xff0c;接口要足够全面&#xff0c;功能完善&#xff0c;首先&#xff0c;第一步就是要找对渠道和方法&#xff0c;这里我们不讨论量化…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...