JVM之内存管理(二)
部分内容来源:JavaGuide+二哥Java
说⼀下 JDK1.6、1.7、1.8 内存区域的变化?
JDK1.6、1.7/1.8 内存区域发⽣了变化,主要体现在⽅法区的实现:
JDK1.6
常量池在方法区
JDK1.7
JDK1.6 使⽤永久代实现⽅法区:JDK1.7 时发⽣了⼀些变化,将字符串常量池、静态变量,存放在堆上
类常量池和运行时常量池仍然在方法区
JDK1.8
在 JDK1.8 时彻底⼲掉了永久代,⽽在直接内存中划出⼀块区域作为元空间
运行时常量池、类常量池都移动到元空间(其实还是在方法区)
说一下常量池位置的变化
常量池包括:
类常量池
运行时常量池
字符串常量池
JDK1.6:常量池在永久代
JDK1.7:运行时常量池+类常量池在永久代,字符串常量池在堆
JDK1.8:运行时常量池+类常量池在元空间,字符串常量池在堆
我们的字符串常量池和静态变量存到哪里
堆
为什么使用元空间替代永久代作为方法区的实现?
永久代有固定大小由MaxPermSize控制,元空间的可用空间由系统的实际可用空间来控制
1、整个永久代有一个 JVM 本身设置的固定大小上限,无法进行调整(也就是受到 JVM 内存的限制),而元空间使用的是本地内存,受本机可用内存的限制,虽然元空间仍旧可能溢出,但是比原来出现的几率会更小。
当元空间溢出时会得到如下错误:java.lang.OutOfMemoryError: MetaSpace
你可以使用 -XX:MaxMetaspaceSize
标志设置最大元空间大小,默认值为 unlimited,这意味着它只受系统内存的限制。-XX:MetaspaceSize
调整标志定义元空间的初始大小如果未指定此标志,则 Metaspace 将根据运行时的应用程序需求动态地重新调整大小。
2、元空间里面存放的是类的元数据,这样加载多少类的元数据就不由 MaxPermSize
控制了
而由系统的实际可用空间来控制,这样能加载的类就更多了。
3、在 JDK8,合并 HotSpot 和 JRockit 的代码时, JRockit 从来没有一个叫永久代的东西, 合并之后就没有必要额外的设置这么一个永久代的地方了。
4、永久代会为 GC 带来不必要的复杂度,并且回收效率偏低
堆里的对象年龄是什么
新生代
我们的新生代分为3个区域
Eden,S0,S1
首先在Eden区域分配,在一个新生代垃圾回收后,如果对象还存活,就会进入S0或者S1,并且对象年龄会加1
老年代
老年代:当新生对对象年龄增加到一定程度(默认为15岁),就会晋升到老年代中
方法区和永久代以及元空间是什么关系
永久代和元空间
是对方法区的两种实现方式
元空间存储什么
运行时常量池
类常量池
方法区存储什么
读取并解析Class文件获取相关信息,将信息存进方法区
方法区里面会存储已被虚拟机加载的 类信息,字段信息,方法信息,常量,静态变量,即时编译器编译后的代码缓存等数据
即运行时常量池和我们的类常量池
说一下运行时常量池
常量池表
Class 文件中除了有类的版本、字段、方法、接口等描述信息外
还有用于存放编译期生成的各种字面量和符号引用的 常量池表
什么是字面量?
字面量是源代码中的固定值的表示法,即通过字面我们就能知道其值的含义。
字面量包括整数、浮点数和字符串字面量
什么是符号引用?
常见的符号引用包括类符号引用、字段符号引用、方法符号引用、接口方法符号
常量池表会在类加载后存放到方法区的运行时常量池中。
运行时常量池的功能类似于传统编程语言的符号表,尽管它包含了比典型符号表更广泛的数据。
既然运行时常量池是方法区的一部分,自然受到方法区内存的限制,当常量池无法再申请到内存时会抛出 OutOfMemoryError
错误。
说一下字符串常量池
字符串常量池 是 JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建
JDK1.7之后
字符串常量和静态变量移动到堆里了
JDK1.7为啥要将字符串常量池移动到堆中
JDK1.7之前我们的字符串常量是存在我们的永久代中
但是永久代我们的GC回收效率太低了,只有在整堆收集(Full GC)的时候才会被执行GC
Java程序中通常会有大量的被创建的字符串等待回收,将字符串常量放到堆中,能够更高效及时地回收字符串内存
什么是整堆回收
什么是整堆收集
堆整个堆内存,包括年轻代和老年代进行垃圾回收的过程
整堆收集的触发条件
1.老年代空间不足
2.方法区空间不足
3.主动调用gc,systrem.gc()进行整堆回收
4.JVM垃圾回收器自适应策略决定执行整堆回收来优化内存使用
5.新生代的对象因为老年代空间不足,导致无法晋升到老年代
什么是直接内存
什么是直接内存
是一种特殊的内存缓冲区,在本地内存上分配的
我们的NIO可以通过Java堆中的DirectByteBuffer对象作为这块内存的引用操作
显著提高性能,避免了在Java堆和Native(本地)堆之间来回复制数据
说一下直接内存的优缺点
优点:
1.速度快
2.减少垃圾回收压力,直接内存不受JVM垃圾回收器的控制
缺点:
1.手动管理,因为我们的内存不受JVM管理,所以我们的JVM不会自动回收它,我们需要手动释放
2.分配和释放的成本较高,不适合频繁进行分配和释放操作
什么是堆外内存
我们不受JVM管理的内存我们都叫做堆外内存
其实我们的堆外内存包含我们的直接内存
说一下对象创建过程
简单区分
初始化对象
为对象分配内存
将分配的内存指向对象
详细区分
在 JVM 中对象的创建,我们从⼀个 new 指令开始
1.类加载检查
⾸先检查这个指令的参数是否能在常量池(类常量池)中定位到⼀个类的符号引⽤
检查这个符号引⽤代表的类是否已被加载、解析和初始化过。如果没有,就先执⾏相应的类加载过程
2.分配内存
类加载检查通过后,接下来虚拟机将为新⽣对象分配内存。
3.初始化零值
分配内存初始化为0
内存分配完成之后,虚拟机将分配到的内存空间(但不包括对象头)都初始化为零值。
4.设置对象头
接下来设置对象头
请求头⾥包含了对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄等信息。
5.执行对象初始化方法
执行初始化方法
流程图解
对象创建过程详解
对象的创建
首先我们要知道我们的对象的创建过程
类加载检查
分配内存
初始化零值
设置对象头
执行初始化方法
1.类加载检查
虚拟机遇到一个new指令时
首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用
并且检查这个符号引用代表的类是否已被加载过、解析和初始化过
如果没有,那必须先执行相应的类加载过程
2.分配内存
在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后便可确定,为对象分配空间的任务等同于把一块确定大小的内存从 Java 堆中划分出来
分配方式有 “指针碰撞” 和 “空闲列表” 两种,选择哪种分配方式由 Java 堆是否规整决定
而 Java 堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定
内存的两种的分配方式
指针碰撞
适用场合:堆内存规整的情况下
原理:用过的内存全部整合到一边,没有用过的内存放在另一边,中间有一个分界指针,只需要向着没用过的内存方向将该指针移动内存位置大小即可
使用该分配方式的GC收集器:Serial,ParNew
空闲列表
适用情况:堆内存不规整的情况下
原理:虚拟机会维护一个列表,该列表中会记录哪些内存块是可用的,在分配的时候,找一块儿足够大的内存块儿来划分给对象实例,最后更新列表记录
使用该分配方式的GC收集器:CMS
内存分配并发问题
虚拟机采用两种方式来保证线程安全
CAS失败重试
CAS是乐观锁的一种实现方式。
乐观锁:不加锁,假设没有冲突去完成某项操作,如果冲突失败就重试,知道成功为止
虚拟机采用CAS配上失败重试的方式保证更新操作的原子性
TLAB
为每一个线程预先在Eden区分配一块内存
JVM在给线程中的对象分配内存时,首先在TLAB分配,当对象大于TLAB中的剩余内存或TLAB的内存已用尽时,再采用上述的CAS进行内存分配
3.初始化零值
内存分配完后,虚拟机需要将分配到的内存空间初始化为零值(不包括对象头)
这一步操作保证了对象的实例字段在Java代码中可以不赋初值就直接使用
程序能访问到这些字段的数据类型所对应的零值
4.设置对象头
初始化零值完成之后,虚拟机要对对象进行必要的设置
例如:这个对象是哪个类的实例,如何才能找到类的元数据信息,对象的哈希码,对象的GC分代年龄等信息
这些信息存放到对象头中
另外,根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置
5.执行init方法
执行完上面的流程之后
从虚拟机视角来看:一个新的对象已经产生了
从Java程序的视角来看:对象创建才刚刚开始,init方法还没有执行,所有的字段都还为0
所以,一般来说,执行new指令之后会接着执行init方法,把对象按照程序员的意愿进行初始化,这样子一个真正可用的对象才算完全产生出来
内存分配的两种方式
指针碰撞
适用场合:堆内存规整的情况下
原理:用过的内存全部整合到一边,没有用过的内存放在另一边,中间有一个分界指针,只需要向着没用过的内存方向将该指针移动内存位置大小即可
使用该分配方式的GC收集器:Serial,ParNew
空闲列表
适用情况:堆内存不规整的情况下
原理:虚拟机会维护一个列表,该列表中会记录哪些内存块是可用的,在分配的时候,找一块儿足够大的内存块儿来划分给对象实例,最后更新列表记录
使用该分配方式的GC收集器:CMS
内存分配并发问题
虚拟机采用两种方式来保证线程安全
CAS失败重试
CAS是乐观锁的一种实现方式。
乐观锁:不加锁,假设没有冲突去完成某项操作,如果冲突失败就重试,知道成功为止
虚拟机采用CAS配上失败重试的方式保证更新操作的原子性
TLAB:Eden区预分配内存
为每一个线程预先在Eden区分配一块内存
JVM在给线程中的对象分配内存时,首先在TLAB分配,当对象大于TLAB中的剩余内存或TLAB的内存已用尽时,再采用上述的CAS进行内存分配
指针碰撞和空闲列表
内存分配有两种⽅式,指针碰撞(Bump The Pointer)、空闲列表(Free List)
指针碰撞
假设 Java 堆中内存是绝对规整的,所有被使⽤过的内存都被放在⼀边,空闲的内存被放在另⼀边,
中间放着⼀个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间⽅向挪动⼀段与对象⼤⼩相等的距离,这种分配⽅式称为“指针碰撞”
空闲列表
如果 Java 堆中的内存并不是规整的,已被使⽤的内存和空闲的内存相互交错在⼀起,那就没有办法简单地进⾏指针碰撞了
虚拟机就必须维护⼀个列表,记录上哪些内存块是可⽤的,在分配的时候从列表中找到⼀块⾜够⼤的空间划分给对象实例,并更新列表上的记录,这种分配⽅式称为“空闲列表”。
两种⽅式的选择由 Java 堆是否规整决定,Java 堆是否规整是由选择的垃圾收集器是否具有压缩整理能⼒决定的
JVM ⾥ new 对象时,堆会发生抢占吗?JVM 是怎么设计来保证线程安全的?
发生抢占的情况
假设 JVM 虚拟机上,每⼀次 new 对象时,指针就会向右移动⼀个对象 size 的距离,⼀个线程正在给 A 对象分配内存,指针还没有来的及修改,另⼀个为 B 对象分配内存的线程,⼜引⽤了这个指针来分配内存,这就发⽣了抢占。
两种可选⽅案来解决这个问题
1.采⽤ CAS 分配重试的⽅式来保证更新操作的原⼦性
2.每个线程在 Java 堆中预先分配⼀⼩块内存,也就是本地线程分配缓冲区(Thread Local Allocation Buffer,TLAB).要分配内存的线程,先在本地缓冲区中分配,只有本地缓冲区⽤完了,分配新的缓存区时才需要同步锁定
对象的内存布局
在 HotSpot 虚拟机⾥,对象在堆内存中的存储布局可以划分为三个部分:
对象头(Header)
实例数据 (Instance Data)
对⻬填充(Padding)
对象头
主要由两部分组成:
第⼀部分存储对象⾃身的运行时数据:哈希码、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等,官⽅称它为 Mark Word,它是个动态的结构,随着对象状态变化。
第⼆部分是类型指针,指向对象的类元数据类型(即对象代表哪个类)
ps:如果对象是⼀个 Java 数组,那还应该有⼀块用于记录数组长度的数据
实例数据
⽤来存储对象真正的有效信息,也就是我们在程序代码⾥所定义的各种类型的字段内容,⽆论是从⽗类继承的,还是⾃⼰定义的。
对齐填充
不是必须的,没有特别含义,仅仅起着占位符的作⽤。
对象的内存布局(简化)
三块区域
对象头
实例数据
对齐填充
对象头的两部分信息
标记字段
用于存储对象自身的运行时数据
例如哈希码,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳等等
类型指针
对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例
对象访问定位的方式
Java 程序会通过栈上的 reference 数据来操作堆上的具体对象。
由于 reference 类型在《Java 虚拟机规范》里面只规定了它是一个指向对象的引用,并没有定义这个引用应该通过什么方式去定位、访问到堆中对象的具体位置,所以对象访问方式也是由虚拟机实现而定的
主流的访问方式主要有使用句柄和直接指针两种
使用句柄(间接访问)
- 如果使用句柄访问的话,Java 堆中将可能会划分出一块内存来作为句柄池,reference 中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自具体的地址信息,其结构如图所示:
直接指针访问
- 如果使用直接指针访问的话,Java 堆中对象的内存布局就必须考虑如何放置访问类型数据的相关信息
- reference 中存储的直接就是对象地址,如果只是访问对象本身的话,就不需要多一次间接访问的开销,如图所示:
对象访问定位(详细)
建立对象就是为了使用对象,我们的 Java 程序通过栈上的 reference 数据来操作堆上的具体对象。
对象的访问方式由虚拟机实现而定,目前主流的访问方式有:使用句柄、直接指针
使用句柄
如果使用句柄的话,那么 Java 堆中将会划分出一块内存来作为句柄池
reference 中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与对象类型数据各自的具体地址信息。
直接指针
如果使用直接指针访问,reference 中存储的直接就是对象的地址
优势
这两种对象访问方式各有优势。
使用句柄来访问的最大好处是 reference 中存储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而 reference 本身不需要修改。
使用直接指针访问方式最大的好处就是速度快,它节省了一次指针定位的时间开销
内存溢出和内存泄漏
内存溢出(Out of Memory,俗称 OOM)和内存泄漏(Memory Leak)是两个不同的概念,但它们都与内存管理有关。
内存溢出
①、内存溢出:是指当程序请求分配内存时,由于没有足够的内存空间满足其需求,从而触发的错误。在 Java 中,这种情况会抛出 OutOfMemoryError。
内存溢出可能是由于内存泄漏导致的,也可能是因为程序一次性尝试分配大量内存,内存直接就干崩溃了导致的。
内存泄漏
②、内存泄漏:是指程序在使用完内存后,未能释放已分配的内存空间,导致这部分内存无法再被使用。随着时间的推移,内存泄漏会导致可用内存逐渐减少,最终可能导致内存溢出。
在 Java 中,内存泄漏通常发生在长期存活的对象持有短期存活对象的引用,长期存活的对象又没有及时释放对短期存活对象的引用,从而导致短期存活对象无法被回收。
用一个比较有味道的比喻来形容就是,内存溢出是排队去蹲坑,发现没坑了;内存泄漏,就是有人占着茅坑不拉屎,占着茅坑不拉屎的多了可能会导致坑位不够用。
内存泄漏的原因
内存泄漏可能的原因有很多种
比如说静态集合类引起内存泄漏、单例模式、数据连接、IO、Socket 等连接、变量不合理的作用域、hash 值发生变化、ThreadLocal 使用不当等
静态集合类引起的内存泄漏
单例对象
单例对象会在初始化后以静态变量的方式在JVM的整个生命周期中存在,如果单例对象持有外部的引用,那么这个外部对象不能被GC回收导致内存泄露
数据连接,IO,Socket等连接
创建的连接不再使用时,需要调用 close 方法关闭连接,只有连接被关闭后,GC 才会回收对应的对象(Connection,Statement,ResultSet,Session)。忘记关闭这些资源会导致持续占有内存,无法被 GC 回收。
变量不合理的作用域
由于作用域原因,导致某些对象分配的内存不会马上释放
Hash值发生变化
ThreadLocal使用不当
JVM堆的内存分区
分为新生代和老年代
新生代:
Eden空间
Survivors空间(分为from和to两个区域)
对象什么时候进入老年代
‘
一.长期存活的对象将进入老年代
二.大对象直接进入老年代
三.动态对象年龄判定
在Survivor空间中相同年龄的所有对象的总和大小等于Survivor空间的一半
那么年龄大于或等于该年龄的对象就可以进入老年代
四.分配担保机制
无法将对象存入Survivor空间
大多数情况下,对象在新生代中 Eden 区分配。
当 Eden 区没有足够空间进行分配时,虚拟机将发起一次 Minor GC
下面我们来进行实际测试一下
当 Eden 区没有足够空间进行分配时,虚拟机将发起一次 Minor GC。
GC 期间虚拟机又发现 allocation1
无法存入 Survivor 空间,所以只好通过 分配担保机制 把新生代的对象提前转移到老年代中去,老年代上的空间足够存放 allocation1
,所以不会出现 Full GC。
执行 Minor GC 后,后面分配的对象如果能够存在 Eden 区的话,还是会在 Eden 区分配内存
什么是Stop The World?什么是Oop Map?什么是安全点?
什么是Stop The World
进行垃圾回收的过程中,会涉及对象的移动
为了保证对象引用更新的正确性,必须暂停所有的用户线程
像这样的停顿,虚拟机设计者形象描述为Stop The World
简称为 STW
什么是Oop Map
Oop Map是面向对象编程映射表
它是 JVM中用于高效垃圾回收(GC) 和内存管理的关键数据结构
它记录了对象内部所有引用字段(指针)的位置,使垃圾回收器能够快速定位并遍历对象中的引用,确保回收的准确性
什么是安全点
什么是安全点:JVM可以安全地暂停所有应用线程以执行特定操作
这些特定的位置主要在:
- 1.循环的末尾(非 counted 循环)
- 2.方法临返回前 / 调用方法的 call 指令后
- 3.可能抛异常的位置
这些位置就叫作安全点(safepoint)
用户程序执行时并非在代码指令流的任意位置都能够在停顿下来开始垃圾收集
而是必须是执行到安全点才能够暂停
用通俗的比喻,假如老王去拉车,车上东西很重,老王累的汗流浃背,但是老王不能在上坡或者下坡休息,只能在平地上停下来擦擦汗,喝口水。
对象一定分配在堆中吗?有没有了解逃逸分析技术
在 Java 中,并不是所有对象都严格在堆上分配内存,虽然堆(Heap)是 Java 对象内存分配的主要区域。
在某些情况下,JVM 的即时编译器(JIT)可能会将对象分配在栈上,这被称为逃逸分析(Escape Analysis)。
也就是说,如果编译器确定一个对象不会在方法外部使用(即对象不会逃逸出方法的作用域),那么该对象可以分配在栈上,而不是堆上
什么是逃逸分析
逃逸分析是指分析指针动态范围的方法,它同编译器优化原理的指针分析和外形分析相关联。
当变量(或者对象)在方法中分配后,其指针有可能被返回或者被全局引用,这样就会被其他方法或者线程所引用,这种现象称作指针(或者引用)的逃逸(Escape)
通俗点讲,当一个对象被 new 出来之后,它可能被外部所调用,如果是作为参数传递到外部了,就称之为方法逃逸
除此之外,如果对象还有可能被外部线程访问到,例如赋值给可以在其它线程中访问的实例变量,这种就被称为线程逃逸。
逃逸分析有什么好处
栈上分配
如果确定一个对象不会逃逸到线程之外,那么久可以考虑将这个对象在栈上分配,对象占用的内存随着栈帧出栈而销毁,这样一来,垃圾收集的压力就降低很多。
同步消除
线程同步本身是一个相对耗时的过程,如果逃逸分析能够确定一个变量不会逃逸出线程,无法被其他线程访问,那么这个变量的读写肯定就不会有竞争, 对这个变量实施的同步措施也就可以安全地消除掉。
标量替换
如果一个数据是基本数据类型,不可拆分,它就被称之为标量。
把一个 Java 对象拆散,将其用到的成员变量恢复为原始类型来访问,这个过程就称为标量替换。
假如逃逸分析能够证明一个对象不会被方法外部访问,并且这个对象可以被拆散,那么可以不创建对象,直接用创建若干个成员变量代替,可以让对象的成员变量在栈上分配和读写。
相关文章:
JVM之内存管理(二)
部分内容来源:JavaGuide二哥Java 说⼀下 JDK1.6、1.7、1.8 内存区域的变化? JDK1.6、1.7/1.8 内存区域发⽣了变化,主要体现在⽅法区的实现: JDK1.6 常量池在方法区 JDK1.7 JDK1.6 使⽤永久代实现⽅法区:JDK1.7 时发…...
蓝桥杯嵌入式第十一届省赛真题
(一)题目 首先要知道P37对应的CubeMx上面的引脚是PB15,给PB15设置成ADC采集。使用到的PA6和PA7的端口要进行定时器配置 100Hz80 000 000/800 *1000 200Hz80 000 000/400 *1000 ADC采集只需要选择好adc1、adc2 再选择好它的通道就可以了,不…...
LLMs之ChatGPT:《Connecting GitHub to ChatGPT deep research》翻译与解读
LLMs之ChatGPT:《Connecting GitHub to ChatGPT deep research》翻译与解读 导读:这篇OpenAI帮助文档全面介绍了将GitHub连接到ChatGPT进行深度代码研究的方法、优势和注意事项。通过连接GitHub,用户可以充分利用ChatGPT强大的代码理解和生成…...
多环境开发
# 应用环境(公共环境,写一些公共配置) spring:profiles:active: dev --- # 设置环境 # 生产环境 spring:config:activate:on-profile: pro server:port: 80 --- # 开发环境 spring:config:activate:on-profile: dev server:port: 81 --- # 测试环境 spring:config:activate:on-…...
游戏引擎学习第269天:清理菜单绘制
回顾并为今天的工作设定目标 昨天我们对调试系统中的菜单处理做了一些清理工作,今天我想继续对它们的展示和使用方式进行一些打磨和改进。今天的计划还不完全确定,我还没有完全决定要做什么,但是我希望能够完成这部分工作,所以我…...
《解锁React Native与Flutter:社交应用启动速度优化秘籍》
React Native和Flutter作为当下热门的跨平台开发框架,在优化应用启动性能方面各有千秋。今天,我们就深入剖析它们独特的策略与方法。 React Native应用的初始包大小对启动速度影响显著。在打包阶段,通过精准分析依赖,去除未使用的…...
Web3 初学者的第一个实战项目:留言上链 DApp
目录 📌 项目简介:留言上链 DApp(MessageBoard DApp) 🧠 技术栈 🔶 1. Solidity 智能合约代码(MessageBoard.sol) 🔷 2. 前端代码(index.html script.js…...
Innovus 25.1 版本更新:助力数字后端物理设计新飞跃
在数字后端物理设计领域,每一次工具的更新迭代都可能为项目带来巨大的效率提升与品质优化。今天,就让我们一同聚焦 Innovus 25.1 版本(即 25.10 版本)的更新要点,探寻其中蕴藏的创新能量。 一、核心功能的强势进 AI…...
Git简介和发展
Git 简介 Git是一个开源的分布式版本控制系统,跨平台,支持Windows、Linux、MacOS。主要是用于项目的版本管理,是由林纳斯托瓦兹(Linux Torvalds)在2005年为Linux内核开发而创建。 起因 在2002年至2005年间,Linux内核开发团队使…...
adb 实用命令汇总
版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/ 基础adb命令 # 重启adb adb kill-server# 查看已连接的设备 adb devices# 进入命令行 adb shell# 使用 -s 参数来指定设备 adb -s <设备序列号> shell…...
DAX 权威指南1:DAX计算、表函数与计算上下文
参考《DAX 权威指南 第二版》 文章目录 二、DAX简介2.1 理解 DAX 计算2.2 计算列和度量值2.3 变量2.3.1 VAR简介2.3.2 VAR的特性 2.4 DAX 错误处理2.4.1 DAX 错误类型2.4.1.1 转换错误2.4.1.2 算术运算错误2.4.1.3 空值或 缺失值 2.4.2 使用IFERROR函数拦截错误2.4.2.1 安全地进…...
使用fdisk 、gdisk管理分区
用 fdisk 管理分区 fdisk 命令工具默认将磁盘划分为 mbr 格式的分区 命令: fdisk 设备名 fdisk 命令以交互方式进行操作的,在菜单中选择相应功能键即可 [rootlocalhost ~]# fdisk /dev/sda # 对 sda 进行分区 Command (m for help): # 进入 fdis…...
Python----神经网络(《Deep Residual Learning for Image Recognition》论文和ResNet网络结构)
一、论文 1.1、论文基本信息 标题:Deep Residual Learning for Image Recognition 作者:Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun 单位:Microsoft Research 会议:CVPR 2016 主要贡献:提出了一种深度残…...
PostgreSQL 的 pg_collation_actual_version 函数
PostgreSQL 的 pg_collation_actual_version 函数 pg_collation_actual_version 是 PostgreSQL 中用于检查排序规则实际版本信息的函数,主要与 ICU (International Components for Unicode) 排序规则相关。 函数基本概念 函数定义 pg_collation_actual_version(…...
使用Simulink开发Autosar Nvm存储逻辑
文章目录 前言Autosar Nvm接口设计模型及接口生成代码及arxmlRTE接口mappingRTE代码分析总结 前言 之前介绍过Simulink开发Dem故障触发逻辑,本文接着介绍另外一个常用的功能-Nvm存储的实现。 Autosar Nvm接口 Autosar Nvm中一般在上电初始化的时调用Nvm_ReadAll获…...
嵌入式STM32学习——继电器
继电器模块引脚说明 VCC(): 供电正极。连接此引脚到电源(通常是直流电源),以提供继电器线圈所需的电流。 GND(-): 地。连接此引脚到电源的负极或地。 IN(或…...
更换内存条会影响电脑的IP地址吗?——全面解析
在日常电脑维护和升级过程中,许多用户都会遇到需要更换内存条的情况。与此同时,不少用户也担心硬件更换是否会影响电脑的网络配置,特别是IP地址的设置。本文将详细探讨更换内存条与IP地址之间的关系,帮助读者理解这两者之间的本质…...
AWS SNS:解锁高并发消息通知与系统集成的云端利器
导语 在分布式系统架构中,如何实现高效、可靠的消息通知与跨服务通信?AWS Simple Notification Service(SNS)作为全托管的发布/订阅(Pub/Sub)服务,正在成为企业构建弹性系统的核心组件。本文深度…...
【Java ee初阶】网络编程 TCP
TCP的socket api 两个核心的类 ServerSocket 创建一个这样的对象,就相当于打开了一个socket文件。 这个socket对象是给服务器专门使用的 这个类本身不负责发送接收。 主要负责“建立连接” Socket 创建一个这样的对象,也就相当于打开了一个socket文…...
达索MODSIM实施成本高吗?哪家服务商靠谱?
在数字化转型的浪潮中,越来越多的制造企业开始关注达索系统的MODSIM技术。记得去年参加行业峰会时,一位来自汽车零部件企业的技术总监向我倾诉了他的困扰:"我们都知道MODSIM能提升研发效率,但听说实施成本很高,又…...
ISP接口隔离原则
任何层次的软件设计如果依赖了它并不需要的东西,就会带来意料之外的麻烦。ISP强调使用多个特定的接口,而不是一个总接口,避免依赖不需要的接口。即不需要则不应该知道。 ISP特点 降低耦合度:客户端只依赖它需要的接口࿰…...
AI Agent(8):安全与伦理考量
引言 AI Agent作为具有一定自主性的智能系统,其行为可能产生深远影响。确保这些系统安全、可靠、符合伦理标准,并遵守相关法规,不仅是技术挑战,也是社会责任。 随着AI Agent能力的增强,其潜在风险也在增加,从数据泄露到决策偏见,从自主性滥用到责任归属不清,这些问题…...
Python3虚拟环境与包管理:项目隔离的艺术
Python3虚拟环境与包管理 为什么需要虚拟环境?虚拟环境工具:你的岛屿建设者一、使用venv创建虚拟环境创建虚拟环境激活虚拟环境退出虚拟环境 二、 包管理:岛上的补给系统2.1 pip:Python的包安装工具基本用法依赖管理 2.2 高级包管…...
23、DeepSeekMath论文笔记(GRPO)
DeepSeekMath论文笔记 0、研究背景与目标1、GRPO结构GRPO结构PPO知识点**1. PPO的网络模型结构****2. GAE(广义优势估计)原理****1. 优势函数的定义**2.GAE(广义优势估计) 2、关键技术与方法3、核心实验结果4、结论与未来方向关键…...
Python自动化-python基础(下)
六、带参数的装饰器 七、函数生成器 运行结果: 八、通过反射操作对象方法 1.添加和覆盖对象方法 2.删除对象方法 通过使用内建函数: delattr() # 删除 x.a() print("通过反射删除之后") delattr(x, "a") x.a()3 通过反射判断对象是否有指定…...
用Python绘制动态彩色ASCII爱心:技术深度与创意结合
引言 在技术博客的世界里,代码不仅仅是解决问题的工具,更可以是表达创意的媒介。今天我将分享一个独特的Python爱心代码项目,它结合了数学之美、ASCII艺术和动态效果,展示了Python编程的无限可能。这个项目不仅能运行展示出漂亮的…...
【C++】红黑树
1.红黑树的概念 是一种二叉搜索树,在每个节点上增加一个存储位表示节点的颜色,Red或black,通过对任何一条从根到叶子的路径上各个结点着色方式的限制,确保没有一条路径会比其他路径长出俩倍,是接近平衡的。 2.红黑树…...
链表头插法的优化补充、尾插法完结!
头插法的优化补充 这边我们将考虑到可以将动态创建链表,和插入新链表到链表头前方,成为新链表头的方法分开,使其自由度上升,在创建完链表后,还可以添加链表元素到成为新的链表头。 就是说可以单独的调用这个insertHea…...
Java多线程(超详细版!!)
Java多线程(超详细版!!) 文章目录 Java多线程(超详细版!!)1. 线程 进程 多线程2.线程实现2.1线程创建2.1.1 继承Thread类2.1.2 实现runnable接口2.1.2.1 思考:为什么推荐使用runnable接口?2.1.2.1.1 更高的…...
超详细fish-speech本地部署教程
本人配置: windows x64系统 cuda12.6 rtx4070 一、下载fish-speech模型 注意:提前配置好git,教程可在自行搜索 git clone https://gitclone.com/github.com/fishaudio/fish-speech.git cd fish-speech 或者直接进GitHub中下载也可以 …...
Flink和Spark的选型
在Flink和Spark的选型中,需要综合考虑多个技术维度和业务需求,以下是在项目中会重点评估的因素及实际案例说明: 一、核心选型因素 处理模式与延迟要求 Flink:基于事件驱动的流处理优先架构,支持毫秒级低延迟、高吞吐的…...
解锁 DevOps 新境界 :使用 Flux 进行 GitOps 现场演示 – 自动化您的 Kubernetes 部署
前言 GitOps 是实现持续部署的云原生方式。它的名字来源于标准且占主导地位的版本控制系统 Git。GitOps 的 Git 在某种程度上类似于 Kubernetes 的 etcd,但更进一步,因为 etcd 本身不保存版本历史记录。毋庸置疑,任何源代码管理服务…...
【从零实现JsonRpc框架#1】Json库介绍
1.JsonCpp第三方库 JSONCPP 是一个开源的 C 库,用于解析和生成 JSON(JavaScript Object Notation)数据。它提供了简单易用的接口,支持 JSON 的序列化和反序列化操作,适用于处理配置文件、网络通信数据等场景。 2.Jso…...
使用FastAPI和React以及MongoDB构建全栈Web应用02 前言
Who this book is for 本书适合哪些人阅读 This book is designed for web developers who aspire to build robust, scalable, and efficient web applications. It caters to a broad spectrum of developers, from those with foundational knowledge to experienced prof…...
JavaScript中的数据类型
目录 前言 基本类型 Number 特殊的数值NaN Infinity和-Infinity String Boolean Undefined null Symbol Undefined和Null的区别 引用类型 Object(对象) Array(数组) Function(函数) 函数声…...
AI 助力,轻松进行双语学术论文翻译!
在科技日新月异的今天,学术交流中的语言障碍仍然是科研工作者面临的一大挑战。尤其是对于需要查阅大量外文文献的学生、科研人员和学者来说,如何高效地理解和翻译复杂的学术论文成为了一大难题。然而,由Byaidu团队推出的开源项目PDFMathTrans…...
第3.2.3节 Android动态调用链路的获取
3.2.3 Android App动态调用链路 在Android应用中,动态调用链路指的是应用在运行时的调用路径。这通常涉及到方法调用的顺序和调用关系,特别是在应用的复杂逻辑中,理解这些调用链路对于调试和性能优化非常重要。 1,动态调用链路获…...
【Android】文件分块上传尝试
【Android】文件分块上传 在完成一个项目时,遇到了需要上传长视频的场景,尽管可以手动限制视频清晰度和视频的码率帧率,但仍然避免不了视频大小过大的问题,且由于服务器原因,网络不太稳定。这个时候想到了可以将文件分…...
大模型中的三角位置编码实现
Transformer中嵌入表示 位置编码的实现 import torch import math from torch import nn# 词嵌入位置编码实现 class EmbeddingWithPosition(nn.Module):"""vocab_size:词表大小emb_size: 词向量维度seq_max_len: 句子最大长度 (人为设定,例如GPT2…...
深入详解人工智能数学基础——微积分中的自动微分及其在PyTorch中的实现原理
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用…...
【Linux学习笔记】系统文件IO之重定向原理分析
【Linux学习笔记】系统文件IO之重定向原理分析 🔥个人主页:大白的编程日记 🔥专栏:Linux学习笔记 文章目录 【Linux学习笔记】系统文件IO之重定向原理分析前言一. 系统文件I/01.1 一种传递标志位的方法1.2 hello.c写文件:1.3 he…...
《React Native与Flutter:社交应用中用户行为分析与埋点统计的深度剖析》
React Native与Flutter作为两款备受瞩目的跨平台开发框架,正深刻地影响着应用的构建方式。当聚焦于用户行为分析与埋点统计时,它们各自展现出独特的策略与工具选择,这些差异和共性不仅关乎开发效率,更与社交应用能否精准把握用户需…...
Cesium高度参考系统
🌍 Cesium高度参考系统趣味探索 🚀 高度参考系统形象比喻 想象一下,你正在玩一个积木游戏: CLAMP_TO_GROUND:积木被"强力胶水"粘在桌面上,无论桌面高低起伏如何 RELATIVE_TO_GROUND:积木放在"微型支架"上,始终保持离桌面固定距离 NONE:积木漂…...
海纳思(Hi3798MV300)机顶盒遇到海思摄像头
海纳思机顶盒遇到海思摄像头,正好家里有个海思Hi3516的摄像头模组开发板,结合机顶盒来做个录像。 准备工作 海纳斯机顶盒摄像机模组两根网线、两个电源、路由器一块64G固态硬盘 摄像机模组和机顶盒都接入路由器的LAN口,确保网络正常通信。 …...
[python] 类
一 介绍 具有相同属性和行为的事物的通称,是一个抽象的概念 三要素: 类名,属性,方法 格式: class 类名: 代码块 class Pepole:name "stitchcool"def getname(self):return self.name 1.1 创建对象(实例化) 格式: 对象名 类名() p1 Pepole()…...
Python中的事件循环是什么?事件是怎么个事件?循环是怎么个循环
在Python异步编程中,事件循环(Event Loop)是核心机制,它通过单线程实现高效的任务调度和I/O并发处理。本文将从事件的定义、循环的运行逻辑以及具体实现原理三个维度展开分析。 一、事件循环的本质:协程与任务的调度器…...
单片机-STM32部分:11、ADC
飞书文档https://x509p6c8to.feishu.cn/wiki/OclUwlkifiRKR2k6iLbczn5tn8g STM32的ADC是一种逐次逼近型模拟数字转换器。 是用于将模拟形式的连续信号转换为数字形式的离散信号的一类设备。 逐次逼近型ADC的原理图下: STM32f103系列有3个ADC,精度为12…...
【含文档+PPT+源码】基于微信小程序的社区便民防诈宣传系统设计与实现
项目介绍 本课程演示的是一款基于微信小程序的社区便民防诈宣传系统设计与实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套…...
Laravel 安全:批量赋值 fillable 与 guarded
Laravel 的模型中有两个 protected 字段 fillable 与 guarded,注意:必须是 protected 以上开放程度。 我们经常通过提交表单进行数据的增删改,为了方便的进行数据批量修改操作 Laravel 提供了批量赋值机制: 假如我们想要在数据库…...
[杂谈随感-13]: 人的睡眠,如何布置床的位置比较有安全?感?
睡眠环境中的床位布置直接影响心理安全感与睡眠质量,需从空间防御性、人体感知机制及环境心理学多维度综合设计。 以下基于科学原理与实践案例,系统解析床位布置的核心策略: 一、空间防御性布局:构建心理安全边界 背靠实体墙&a…...