提高Java程序性能!了解可达性分析算法、强软弱虚引用和三色标记GC的过程,避免不可达对象阻碍程序性能!

news2025/1/15 3:22:21

文章目录

    • 🍊 可达性分析算法
    • 🍊 强软弱虚引用
      • 🎉 强引用
      • 🎉 软引用
      • 🎉 弱引用
      • 🎉 虚引用
    • 🍊 不可达对象GC的过程
      • 🎉 GC中不可达对象的回收过程
        • 📝 1. 标记阶段
        • 📝 2. 清除阶段
        • 📝 3. 压缩阶段
        • 📝 4. 回收阶段
        • 📝 5. 总结
    • 🍊 三色标记
      • 🎉 白色标记——对象不可达
      • 🎉 黑色标记——已经被访问
      • 🎉 灰色标记——部分对象未被扫描
      • 🎉 总结

📕我是廖志伟,一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专家博主、清华大学出版社签约作者、产品软文创造者、技术文章评审老师、问卷调查设计师、个人社区创始人、开源项目贡献者。🌎跑过十五公里、徒步爬过衡山、🔥有过三个月减肥20斤的经历、是个喜欢躺平的狠人。

📘拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、Spring MVC、SpringCould、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RockerMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。🎥有从0到1的高并发项目经验,利用弹性伸缩、负载均衡、报警任务、自启动脚本,最高压测过200台机器,有着丰富的项目调优经验。

📙经过多年在CSDN创作上千篇文章的经验积累,我已经拥有了不错的写作技巧。同时,我还与清华大学出版社签下了四本书籍的合约,并将陆续在明年出版。这些书籍包括了基础篇、进阶篇、架构篇的📌《Java项目实战—深入理解大型互联网企业通用技术》📌,以及📚《解密程序员的思维密码–沟通、演讲、思考的实践》📚。具体出版计划会根据实际情况进行调整,希望各位读者朋友能够多多支持!

以梦为马,不负韶华

希望各位读者大大多多支持用心写文章的博主,现在时代变了,信息爆炸,酒香也怕巷子深,博主真的需要大家的帮助才能在这片海洋中继续发光发热,所以,赶紧动动你的小手,点波关注❤️,点波赞👍,点波收藏⭐,甚至点波评论✍️,都是对博主最好的支持和鼓励!

  • 💂 博客主页: 我是廖志伟
  • 👉开源项目:java_wxid
  • 🌥 哔哩哔哩:我是廖志伟
  • 🎏个人社区:幕后大佬
  • 🔖个人微信号SeniorRD

💡在这个美好的时刻,本人不再啰嗦废话,现在毫不拖延地进入文章所要讨论的主题。接下来,我将为大家呈现正文内容。

CSDN
了解可达性分析算法、强软弱虚引用和三色标记GC的过程,避免不可达对象阻碍程序性能!

🍊 可达性分析算法

可达性分析算法是一种基本的垃圾回收算法,用于动态回收Java程序中不再使用的对象,以释放占用的内存空间。在该算法中,GC Root节点是可达性分析的起点,通过遍历整个堆内存中的对象,找出所有可达的对象,然后将不可达对象标记为白色,并最终清除它们占用的内存空间。

可以作为GC Root节点的引用点有几种类型,包括虚拟机栈中引用的对象、本地方法栈中引用的对象、方法区中的静态属性引用的对象、方法区中的常量引用的对象、Java虚拟机内部的引用以及锁引用的对象等。这些引用点可以作为可达性分析的起点,遍历整个堆内存中的对象,找出所有可达的对象,最终将不可达的对象标记为白色,并清除它们占用的内存空间。

需要注意的是,可达性分析算法并不能完全避免内存泄漏,因为有些对象虽然不再被直接引用,但是还存在于某些数据结构中,或者被缓存着,这些对象也无法被回收。因此,在编写程序时,需要尽可能地减少无用的对象持有问题,及时释放不再需要的对象,避免内存泄漏的出现。

举几个例子,在Web应用中,可能会创建一些连接数据库的对象,但是请求处理完毕后,这些对象可能就不再需要了,但是由于某些原因,这些对象还被某些数据结构(如Map、List等)持有着,导致无法被回收,一直占用着内存空间,这就是内存泄漏的一种情况。

为了优化可达性分析算法的效率,可以采用增量式的可达性分析和并发标记等技术,以减小程序停顿的时间,提高程序的性能和稳定性。

通过GC Root节点作为起点,遍历整个堆内存中的对象,找出所有可达的对象,最终将不可达的对象标记为白色,并清除它们占用的内存空间。在编写程序时,需要避免无用的对象持有问题,及时释放不再需要的对象,避免内存泄漏的出现。在垃圾回收器实现中,也需要结合一些优化技术,提高可达性分析的效率,从而保证程序的性能和稳定性。

可达性分析算法是一种静态分析算法,通常用于确定程序中哪些对象是“可达”的,即哪些对象可以被程序访问到,哪些对象是不可访问的。

举个例子,假设有一个程序,其中有三个对象:对象A、对象B和对象C。对象A指向对象B,对象B又指向对象C。那么我们可以将这三个对象构建成一个对象图,其中对象A指向对象B,对象B指向对象C,如下所示:

A -> B -> C

假设程序中有一个全局变量root,它指向对象A,那么我们可以将root标记为已访问的根节点。然后从根节点开始遍历对象图,找到所有可达的对象。在这个例子中,从根节点root开始遍历,可以访问到对象A、对象B和对象C,所以它们都被标记为已访问的可达对象。而其他未被访问的对象则是不可达的,如下所示:

root -> A -> B -> C (可达)
D (不可达)

这个例子只有三个对象比较简单,实际上程序中可能有成千上万个对象,构建对象图和遍历对象图的过程可能比较复杂。但可达性分析算法的底层执行流程是类似的,都是建立对象图、标记根节点、遍历对象图,最后输出可达对象。

以下是可达性分析算法底层执行流程:

  1. 定义对象和引用:在分析程序之前,需要确定程序中所有的对象和引用。对象可以是任何类型的数据,包括简单类型(如整数和布尔值)和复杂类型(如数组和对象)。引用是指指向对象的变量或指针。

  2. 建立对象图:将所有的对象和引用按照它们之间的关系构建成一个对象图。对象图可以理解为一个有向图,其中节点表示对象,边表示引用。

  3. 标记根节点:为了开始分析,需要标记一些根节点。根节点是那些可以从程序中访问到的对象,如全局变量、局部变量和函数参数等。将这些根节点标记为已访问。

  4. 遍历对象图:从根节点开始遍历对象图,找到所有可达的对象。在遍历过程中,将访问过的对象标记为已访问,并记录它们的引用关系。

  5. 输出可达对象:遍历完成后,所有被访问过的对象都被标记为已访问,而未被访问的对象则是不可达的。可达性分析算法可以输出所有被访问过的对象,也可以输出被访问次数超过一个阈值的对象,以帮助优化程序。

以下是一个简单的例子来说明可达性分析算法的执行流程:

  1. 定义对象和引用:假设我们要分析以下程序:
function foo() {
  let a = {prop1: "value1"};
  let b = {prop2: "value2"};
  a.next = b;
  return a;
}

let c = foo();

在这个程序中,我们有三个对象,分别是 abc,以及两个引用,分别是 a.next 和返回值 c

  1. 建立对象图:我们可以将对象和引用构建成一个对象图,其中 ab 是节点,a.next 是从 ab 的边。这样,我们就得到了以下对象图:
a --> b

c
  1. 标记根节点:在这个程序中,根节点是 c,因为它是从程序的起点开始访问的。

  2. 遍历对象图:从根节点 c 开始遍历对象图,我们可以找到所有可达的对象。首先访问 c,然后访问 a,发现它有一个指向 b 的引用,于是继续访问 b。遍历完后,我们可以得到以下已访问的对象:

c, a, b
  1. 输出可达对象:在这个例子中,所有被访问过的对象都被标记为已访问,因此所有的对象都是可达的。如果我们要输出被访问次数超过一个阈值的对象,那么在这个例子中,所有对象的访问次数都是 1,因此没有超过阈值的对象。

总的来说,可达性分析算法的底层执行流程就是建立对象图、标记根节点、遍历对象图,最后输出可达对象。

🍊 强软弱虚引用

在 Java 中,垃圾回收器会负责回收无用的对象,以释放内存空间。但是,这个过程并不是完美的,如果某个对象仍然被引用,但是又不需要使用它了,那么这个对象就处于一种尴尬的状态。在这个时候,就需要引入强,软,弱和虚四种引用类型,来告诉垃圾回收器对这些对象如何处理,以确保内存的合理利用。

🎉 强引用

强引用是最常见的引用类型,也是默认的引用类型。如果一个对象具有强引用关系,那么垃圾回收器就不会回收该对象。强引用可以通过 new 关键字创建,例如:

Object obj = new Object();

在这个例子中,obj 引用了一个 Object 对象,垃圾回收器不能回收这个对象,除非 obj 被赋值为 null,或者整个程序执行完毕,obj 被销毁。

🎉 软引用

软引用是用来描述还有用,但是不必须回收的对象。如果一个对象只有软引用关系,那么当系统内存不足的时候,就会把这些对象列入回收范围,进行第二次垃圾回收。如果第二次回收之后,还是没有足够的内存,才会抛出异常。可以通过 SoftReference 类创建软引用,例如:

SoftReference<Object> obj = new SoftReference<>(new Object());

在这个例子中,obj 引用了一个 Object 对象,但是这个引用是软引用。如果系统内存不足,垃圾回收器就会回收这个对象。需要注意的是,软引用并不会立即被回收,而是在系统内存不足的时候,才会被回收。

🎉 弱引用

弱引用是用来描述这个对象还有用,但是由于没有强引用关系,只能生存到下一次垃圾回收器进行垃圾收集。如果一个对象只有弱引用关系,那么当系统进行垃圾回收的时候,无论系统内存是否充足,都会把这个对象回收掉。可以通过 WeakReference 类来创建弱引用,例如:

WeakReference<Object> obj = new WeakReference<>(new Object());

在这个例子中,obj 引用了一个 Object 对象,但是这个引用是弱引用。如果系统进行垃圾回收的时候,这个对象的强引用全部失效,那么这个对象就会被回收掉。需要注意的是,弱引用具有不确定性,也就是说,它的回收时间不可预测,可能在任何时候被回收。

🎉 虚引用

虚引用是用来描述一些被强引用关系以外,没有任何引用关系的对象。如果一个对象只有虚引用关系,那么在任何时候,都可能被垃圾回收器回收掉。虚引用的存在不会对结构造成任何影响,也无法通过虚引用来获取对象实例。可以通过 PhantomReference 类来创建虚引用,例如:

PhantomReference<Object> obj = new PhantomReference<>(new Object(), new ReferenceQueue<>());

在这个例子中,obj 引用了一个 Object 对象,但是这个引用是虚引用。在任何时候都可能被垃圾回收器回收掉,而且这个对象被回收时,会把回收的信息放入一个队列中,可以通过这个队列来判断某个对象是否已经被回收了。

需要注意的是,虚引用不是用来获取对象实例的,因为在任何时候都不可能通过虚引用来获取对象的引用。虚引用的主要作用是用来跟踪对象被垃圾回收的状态,从而在对象被销毁之前进行一些必要的清理操作。

总结一下,四种引用类型的特点分别是:

  • 强引用:在任何时候都不会被回收,只有引用关系被断开,才会被回收。
  • 软引用:只有在系统内存不足的时候才会被回收,可以用来缓存一些占用内存比较大的对象。
  • 弱引用:只要没有强引用关系,就可以被回收,用来描述一些缓存性质的数据。
  • 虚引用:不能通过虚引用来获取对象实例,只是用来跟踪对象被回收的状态,或者进行一些必要的清理操作。

下面再举一些例子来说明四种引用类型的应用场景。

强引用的应用场景

强引用最常见的应用场景就是在创建对象的时候,默认创建的引用就是强引用。这种引用关系非常紧密,只要引用关系存在,垃圾回收器就不会回收这个对象。需要注意的是,强引用可能会导致内存泄露,因为一旦这个引用关系被建立起来,就很难被断开了。

软引用的应用场景

通常情况下,软引用用来缓存一些占用内存比较大的对象。比如,我们可以将图片资源缓存在软引用中,当用户返回到之前浏览过的图片时,可以直接从软引用中取出图片,而不必重新加载。如果系统内存充足,这些缓存的图片就能够一直保存下去,等到系统内存不足的时候,就会自动被回收掉。这种方式既能保证用户体验,又能尽可能地节省内存空间,是一种比较优秀的实践方法。

弱引用的应用场景

弱引用主要用来描述一些缓存性质的数据,比如一些不经常使用的数据。例如,我们可以将某个对象的数据缓存在弱引用中,当这个对象不再被使用时,弱引用也会自动被回收掉。这种方式既能够节省内存空间,又能够避免内存泄露的问题,是一种比较常见的实践方法。

虚引用的应用场景

虚引用的主要作用是用来跟踪对象被垃圾回收的状态,从而在对象被销毁之前进行一些必要的清理操作。比如,在某些情况下,我们需要释放掉一些占用资源比较大的对象,但是在释放之前需要进行一些必要的清理工作。这个时候,就可以使用虚引用来跟踪对象被回收的状态,一旦对象被回收了,就可以调用相应的清理方法来进行必要的清理操作。虚引用还可以用来实现一些比较高级的技巧,比如对象的拷贝和序列化等。

🍊 不可达对象GC的过程

当一个对象不再被引用时,它就成为了不可达对象。不可达对象将被Java虚拟机的垃圾回收算法回收。

例如,当一个字符串变量str不再指向字符串对象"Hello"时,这个字符串对象就成为了不可达对象,它将被回收。

String str = "Hello";
str = null; //字符串"Hello"成为了不可达对象

🎉 GC中不可达对象的回收过程

📝 1. 标记阶段

当垃圾回收器开始工作时,它会遍历内存中的所有对象,并对不再被引用的对象进行标记。在标记阶段,垃圾回收器会找出所有的不可达对象,并将它们标记为可回收对象。

例如,当一个字符串变量str不再指向字符串对象"Hello"时,这个字符串对象将被标记为可回收对象。

String str = "Hello";
str = null; //"Hello"被标记为可回收对象
📝 2. 清除阶段

在清除阶段,垃圾回收器将回收不再被引用的对象所占用的内存。在Java虚拟机中,清除阶段通常采用的是标记清除算法。

例如,当一个字符串变量str不再指向字符串对象"Hello"时,这个字符串对象将被清除。

String str = "Hello";
str = null; //"Hello"被清除
📝 3. 压缩阶段

在压缩阶段,垃圾回收器将移动剩余对象,填充内存中的空洞,以便更好地利用内存空间。在Java虚拟机中,压缩阶段通常采用的是压缩算法。

例如,当一个字符串变量str不再指向字符串对象"Hello"时,Java虚拟机将会在内存中留下空洞。在压缩阶段,垃圾回收器将移动剩余对象,填充这个空洞,以便更好地利用内存空间。

String str = "Hello";
str = null; //Java虚拟机留下了空洞
📝 4. 回收阶段

在回收阶段,垃圾回收器将执行finalize()方法,以便在对象被回收时进行一些清理工作或日志记录。如果对象在finalize()方法中重新与引用链上的任何一个对象建立关联,那它将被移出“即将回收”的集合。如果对象在finalize()方法执行后仍然不再被引用,那它就会被彻底回收了。

例如,当一个对象obj不再被引用时,Java虚拟机将把它放到F-Queue的队列里面。这个队列里面会启用一个低优先级的线程,去读取这些不可达的对象,然后一个一个的调用对象的finalize方法。如果对象的finalize方法被覆盖过,被调用过,这个时候虚拟机将这两种情况都视为“没有必要执行”。

public class MyObject {
    @Override
    protected void finalize() throws Throwable {
        System.out.println("MyObject被回收了");
    }
}

public static void main(String[] args) {
    MyObject obj = new MyObject();
    obj = null;
    System.gc(); //"MyObject被回收了"
}
📝 5. 总结

垃圾回收算法是一种自动内存管理技术,它的目的是确保在运行程序时不会发生内存泄漏和内存溢出。Java虚拟机通过垃圾回收算法回收不再被引用的对象,以便更好地利用内存空间。当对象不再被引用时,它可以被回收。垃圾回收过程可以分为标记、清除、压缩和回收4个阶段,其中回收阶段是最后一次机会,它执行的是finalize()方法,以便在对象被回收时进行清理工作或日志记录。一旦对象被回收,它就不能再被引用了。

🍊 三色标记

三色标记算法是一种常用的垃圾回收算法,它基于可达性分析的思想,用三种不同颜色的标记来表示对象的状态,帮助程序判断哪些内存可以被回收,哪些内存仍然需要使用。

🎉 白色标记——对象不可达

白色标记表示对象不可达,即程序不再使用该对象。当程序申请一块内存时,操作系统会给这块内存分配地址,并将其标记为白色。随着程序的执行,这块内存可能会被程序引用,也可能不再被引用。如果这块内存处于不再被引用的状态,则称其为垃圾内存,需要及时回收以释放空间。

例如,当程序执行完一个函数后,函数中使用的一些变量所占用的内存可能就不再需要了。此时,这些变量占用的内存就可以被标记为白色,等待垃圾回收器回收。

🎉 黑色标记——已经被访问

黑色标记表示对象已经被扫描过了,垃圾回收器已经检查了该对象与其关联的对象,并且将这些对象标记为黑色。这些对象不再需要被扫描了,因为它们已经被确认为可达对象,程序会继续使用它们。

例如,当程序遍历一个链表时,每一个节点所占用的内存会被标记为黑色。如果遍历结束后某些节点没有被标记为黑色,说明这些节点不再被程序使用,可以被回收。

🎉 灰色标记——部分对象未被扫描

灰色标记表示对象未被扫描到,但是它仍有可能被引用,因此需要继续扫描其关联的对象。在垃圾回收的过程中,黑色对象和灰色对象一起组成了活动对象,白色对象则是未被引用的垃圾对象。

例如,当程序执行一个递归函数时,每次函数调用都会生成新的内存并标记为灰色,这些内存表示还需要进一步扫描其关联的对象。随着程序的执行,一部分内存可能被标记为黑色,表示已经扫描过了,但还有一部分内存处于灰色状态,需要继续扫描。

🎉 总结

三色标记算法是一种可达性分析的垃圾回收算法,通过不同颜色的标记表示对象的状态,帮助程序判断哪些内存可以被回收,哪些内存仍然需要使用。白色标记表示对象不可达,黑色标记表示已经被扫描过了,灰色标记表示部分对象未被扫描。该算法具有效率高、精度高等优点,被广泛应用于各种编程语言中。

1.在Java中,JVM自带的垃圾回收器就使用了三色标记算法。JVM会维护一个对象的引用计数,当对象的引用计数为0时,就将其标记为白色。在垃圾回收的过程中,JVM会使用三色标记算法,将对象分为白色、黑色和灰色三种状态,并通过扫描算法来确定哪些内存可以被回收。

2.在Python中,垃圾回收器也使用了三色标记算法。Python中的内存管理是基于引用计数的,当一个对象的引用计数为0时,就将其标记为白色。在垃圾回收的过程中,Python会使用三色标记算法,将对象分为白色、黑色和灰色三种状态,并通过扫描算法来确定哪些内存可以被回收。

3.在JavaScript中,V8引擎使用了三色标记算法。V8引擎是Chrome浏览器的核心部分,用于解析和执行JavaScript代码。V8引擎中的垃圾回收器是基于标记-清除算法和三色标记算法的,可以高效地回收不再使用的内存。

总的来说,三色标记算法是一种非常优秀的垃圾回收算法,可以有效地管理内存,提高程序的性能。该算法已经被广泛应用于各种编程语言中,成为了内存管理的重要工具。

CSDN

🔔如果您需要转载或者搬运这篇文章的话,非常欢迎您私信我哦~

希望各位读者大大多多支持用心写文章的博主,现在时代变了,信息爆炸,酒香也怕巷子深,博主真的需要大家的帮助才能在这片海洋中继续发光发热,所以,赶紧动动你的小手,点波关注❤️,点波赞👍,点波收藏⭐,甚至点波评论✍️,都是对博主最好的支持和鼓励!

  • 💂 博客主页: 我是廖志伟
  • 👉开源项目:java_wxid
  • 🌥 哔哩哔哩:我是廖志伟
  • 🎏个人社区:幕后大佬
  • 🔖个人微信号SeniorRD

📥博主的人生感悟和目标

探寻内心世界,博主分享人生感悟与未来目标

  • 🍋程序开发这条路不能停,停下来容易被淘汰掉,吃不了自律的苦,就要受平庸的罪,持续的能力才能带来持续的自信。我本身是一个很普通程序员,放在人堆里,除了与生俱来的盛世美颜,就剩180的大高个了,就是我这样的一个人,默默写博文也有好多年了。
  • 📺有句老话说的好,牛逼之前都是傻逼式的坚持,希望自己可以通过大量的作品、时间的积累、个人魅力、运气、时机,可以打造属于自己的技术影响力。
  • 💥内心起伏不定,我时而激动,时而沉思。我希望自己能成为一个综合性人才,具备技术、业务和管理方面的精湛技能。我想成为产品架构路线的总设计师,团队的指挥者,技术团队的中流砥柱,企业战略和资本规划的实战专家。
  • 🎉这个目标的实现需要不懈的努力和持续的成长,但我必须努力追求。因为我知道,只有成为这样的人才,我才能在职业生涯中不断前进并为企业的发展带来真正的价值。在这个不断变化的时代,我必须随时准备好迎接挑战,不断学习和探索新的领域,才能不断地向前推进。我坚信,只要我不断努力,我一定会达到自己的目标。

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

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

相关文章

远程IO模块物联网应用提高工业自动化生产效率

远程IO模块是一款常用于工业自动化领域的通讯设备&#xff0c;它可以实现远程监测&#xff0c;帮助企业更加有效地掌控生产状态&#xff0c;提高生产效率。远程IO模块的作用是将分散的输入输出信号集中管理&#xff0c;实现实时数据采集、传输与控制。 远程IO模块通过安装在设…

Windows / Ubuntu 连wifi,网线连接旭日X3派以共享网络

首先&#xff0c;PC电脑连好wifi Windows 找到【控制面板->网络和Internet->网络和共享中心->查看网络状态和任务->更改适配器设置】 找到WLAN&#xff0c;右键【属性->共享】勾上允许&#xff0c;然后【确定】。 Ubuntu 打开设置&#xff0c;找到有线设置…

2024SCI经验心得分享---如何在零基础、导师基本放养的情况下---发表自己的第一篇SCI(三区)经验分享篇

本期的经验分享&#xff0c;采访到了我的一位非常非常非常优秀的师妹&#xff0c;师妹于今年6月份投稿&#xff0c;10月份录用&#xff0c;历时四个月录用了自己的第一篇SCI&#xff08;三区&#xff09;的文章图像处理类的&#xff0c;同时师妹也取得了很多其他优秀的荣誉。 众…

Python数据结构(栈)

Python数据结构&#xff08;栈&#xff09; 栈(stack)&#xff0c;有些地方称为堆栈&#xff0c;是一种容器&#xff0c;可存入数据元素、访问元素、删除元素&#xff0c;它的特点在于只能允许在容器的一端(称为栈顶端指标&#xff0c;英语: top)进行加入数据(英语: push)和输…

手撕Vue-实现计算属性

前言 经过上一篇的学习, 完成了将数据代理到了 Nue 的实例上方&#xff0c;这个我们已经撕完了。接下来要实现的是计算属性&#xff0c;计算属性的实现原理是通过 Object.defineProperty() 来实现的&#xff0c;我们先来看看计算属性的使用。 看之前先来改造一下我们的代码基础…

DevExpress WinForms地图组件 - 轻松集成地图功能到应用程序

DevExpress WinForms地图控件允许您在WinForms应用程序中合并地图服务&#xff0c;您可以选择现有的地图资源&#xff0c;如如Bing或OpenStreetMap&#xff0c;或者在公司网络中创建自己的地图数据服务器。DevExpress WinForms地图控件完全支持矢量和笛卡尔坐标地图。 DevExpr…

Plex踩坑——移动缓存目录

plex在生成缩略图、刮削视频的时候会生成大量的缓存文件&#xff0c;占用磁盘空间。 plex默认缓存存储位置为C:\Users\xxx\AppData\Local\Plex Media Server&#xff0c;并且这个路径在plex设置中无法更改。 可以通过修改注册表的方式修改该路径。 首先推出plex账号&#xff…

学习视觉CV Transformer (1)--Transformer介绍

先放Transformer的经典文章 Attention Is All You Need 论文代码&#xff1a;https://paperswithcode.com/paper/attention-is-all-you-need Transformer结构是google在17年的Attention Is All You Need论文中提出&#xff0c;首先主要是在自然语言处理NLP方面应用&#xff0c…

万物“邮”爱,百余志愿者参与邮票艺术共创助力生物多样性

邮票作为生动形象的文化载体&#xff0c;传承着中华文化的历史和文明。自邮票问世以来&#xff0c;就以其精美的设计和图案&#xff0c;成为人们珍藏文化遗产和学习历史文化的窗口。野生动物保护一直是人们所关注的热门话题&#xff0c;相关部门也为宣传、拯救、保护珍贵濒危野…

[量化投资-学习笔记001]Python+TDengine从零开始搭建量化分析平台-数据存储

目录 0. 简介1. 获取交易数据2. 数据库搭建2.1. 数据库安装2.2. 创建数据库2.3. 创建超级表2.4. 创建子表 3.数据导入4. Grafana 安装4.1. 安装Grafana4.2. 安装TDengine插件 附件数据导入脚本历史交易数据-1分钟K线 0. 简介 Python&#xff1a;最常用的量化分析语言&#xff0…

【超参数研究02】使用随机搜索优化超参数

一、说明 在神经网络训练中&#xff0c;超参数也是需要优化的&#xff0c;然而在超参数较多&#xff08;大于3个&#xff09;后&#xff0c;如果用穷举的&#xff0c;或是通过经验约摸实现就显得费时费力&#xff0c;无论如何&#xff0c;这是需要研究、规范、整合的要点&#…

【自用】知识点梳理 自动控制第Z章 离散s

目录标题 离散XXXQ1 离散化的表达式和传递函数怎么匹配上&#xff1f; 离散系统的分析与校正Q ZOH有什么作用K ZOH的Z变换✨K Z变换表格模拟化矫正ZOH的等效Q 为什么离散化之后幅值会变化&#xff1f;Q 模拟化校正中ZOH环节为什么需要等效成惯性环节&#xff1f; 离散化的方法Q…

Android dumpsys介绍

文章目录 一、需求二、环境三、相关概念3.1 dumpsys3.2 Binder3.3 管道 四、dumpsys指令的使用4.1 dumpsys使用4.2 dumpsys指令语法 五、详细设计5.1 dumpsys流程图5.2 dumpsys查看电池信息5.2.1 dumpsys battery指令5.2.2 service->dump打印函数 5.3 dumpsys源码分析5.3.1 …

[support2022@cock.li].faust、[tsai.shen@mailfence.com].faust勒索病毒数据怎么处理|数据解密恢复

引言&#xff1a; 威胁网络安全的恶意软件不断涌现&#xff0c;而[support2022cock.li].faust勒索病毒则是其中的一员。这个网络黑暗角落的新星&#xff0c;以其数据绑架的方式&#xff0c;一度成为数据安全的威胁焦点。本文将探究[support2022cock.li].faust勒索病毒的运作方…

Cypress的安装与启动

目录 一&#xff1a;Cypress介绍 二&#xff1a;安装与使用 1、下载node.js 2、安装Cypress 3、启动Cypress 3、解决异常 三&#xff1a;总结 一&#xff1a;Cypress介绍 Cypress 是为现代网络而构建的下一代前端测试工具&#xff0c;用于解决开发者和 QA 工程师在测试现…

【Hydro】水文模型比较框架MARRMoT - 包含47个概念水文模型的Matlab代码

目录 说明源代码运行实例workflow_example_1.mworkflow_example_2.mworkflow_example_3.mworkflow_example_4.m 测试1、 结构体兼容性问题2、append的兼容性问题3、修改后的MARRMoT_model.m 说明 MARRMoT是一个新的水文模型比较框架&#xff0c;允许不同概念水文模型结构之间的…

BandZip 免费纯净快速的文件压缩/解压缩软件

BandZip 功能齐全、性能优异的免费文件压缩和解压缩工具。版本 7.x 及以上有广告&#xff0c;安装 7.x 以下版本即可。 功能以及特性 支持多种常见的压缩格式&#xff0c;包括 ZIP、RAR、7Z、TAR 等&#xff1b;高效的压缩算法&#xff0c;能够将文件压缩到较小的体积&#…

【网络安全 --- 任意文件下载漏洞(1)】任意文件下载漏洞

一&#xff0c;环境&#xff0c;工具准备 1-1 VMVare 16 虚拟机及下载安装&#xff08;资源&#xff09; 请参考以下博客安装&#xff08;特详细&#xff09;&#xff1a;【网络安全 --- 工具安装】VMware 16.0 详细安装过程&#xff08;提供资源&#xff09;-CSDN博客【网络安…

vue2vue3--render函数(h)

目录 h函数 方法1. 在Options API中的使用 方法2. 在Composition API中的使用 Vue 2中的渲染函数 ​基础​ vue2 vue3 vue3--声明渲染函数 节点、树以及虚拟 DOM ​虚拟 DOM​ createElement 参数 深入数据对象 约束 vue2 vue3 使用 JavaScript 代替模板功能…

使用cpolar内网穿透实现远程Stackedit Markdown编辑器

文章目录 1. docker部署Stackedit2. 本地访问3. Linux 安装cpolar4. 配置Stackedit公网访问地址5. 公网远程访问Stackedit6. 固定Stackedit公网地址 StackEdit是一个受欢迎的Markdown编辑器&#xff0c;在GitHub上拥有20.7k Star&#xff01;&#xff0c;它支持将Markdown笔记保…