Java进阶(垃圾回收GC)——理论篇:JVM内存模型 垃圾回收定位清除算法 JVM中的垃圾回收器

在这里插入图片描述

前言

JVM作为Java进阶的知识,是需要Java程序员不断深度和理解的。

本篇博客介绍JVM的内存模型,对比了1.7和1.8的内存模型的变化;介绍了垃圾回收的语言发展;阐述了定位垃圾的方法,引用计数法和可达性分析发以及垃圾清除算法;然后介绍了Java中的垃圾回收器,由串行、到并行再到并发,最后到G1的演变;最后给出了垃圾回收器的对比和使用指引。

其他相关的JVM博客文章如下:

  • Java进阶(1)——JVM的内存分配 & 反射Class类的类对象 & 创建对象的几种方式 & 类加载(何时进入内存JVM)& 注解 & 反射+注解的案例
  • Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化

系列文章合集如下:
【合集】Java进阶——Java深入学习的笔记汇总 & 再论面向对象、数据结构和算法、JVM底层、多线程、类加载 …

目录

  • 前言
  • 引出
  • JVM内存模型
    • JDK1.7
    • JDK1.8
  • 垃圾回收基础
    • 栈空间和堆空间
    • 垃圾回收的语言发展
  • 如何定位垃圾
    • 引用计数法
    • 可达性分析方法
  • 垃圾清除算法
    • 标记-清除
    • 标记-复制
    • 标记-压缩
  • 垃圾回收器
    • 总览
    • 串行Serial 和 Serial-Old
    • 并行Parallel (jdk1.8默认)
    • 并发ParNew,CMS
      • 三色标记法
    • Garbage FirstGC回收器
      • 在jdk1.8用G1
      • G1垃圾回收过程
      • G1的四大特点
      • G1的适用场景
  • 垃圾回收器的使用
    • G1调优快速使用
    • 8种GC回收器的比较
    • 怎么选择GC回收器
  • 总结

引出


1.JVM的内存模型,对比了1.7和1.8的内存模型的变化;
2.垃圾回收的语言发展;定位垃圾的方法,引用计数法和可达性分析发以及垃圾清除算法;
3.Java中的垃圾回收器,由串行、到并行再到并发,最后到G1的演变;
4.垃圾回收器的对比和使用指引。

JVM内存模型

JDK1.7

在这里插入图片描述

Young区(年轻代区):Young区被划分为三部分,Eden区和两个大小严格相同的Survivor区,其中,Survivor区间中,某一时刻只有其中一个是被使用的,另外一个留做垃圾收集时复制对象用,在Eden区间变满的时候, GC就会将存活的对象移到空闲的Survivor区间中,根据JVM的策略,在经过几次垃圾收集后,任然存活于Survivor的对象将被移动到Tenured区间

Tenured 年老区:Tenured区主要保存生命周期长的对象,一般是一些老的对象,当一些对象在Young复制转移一定的次数以后,对象就会被转移到Tenured区,一般如果系统中用了application级别的缓存,缓存中的对象往往会被转移到这一区间。

Perm 永久区:Perm代主要保存class,method,filed对象,这部份的空间一般不会溢出,除非一次性加载了很多的类,不过在涉及到热部署的应用服务器的时候,有时候会遇到java.lang.OutOfMemoryError : PermGen space 的错误,造成这个错误的很大原因就有可能是每次都重新部署,但是重新部署后,类的class没有被卸载掉,这样就造成了大量的class对象保存在了perm中,这种情况下,一般重新启动应用服务器可以解决问题。

Virtual区:最大内存和初始内存的差值,就是Virtual区。

JDK1.8

jdk1.8的内存模型是由2部分组成,年轻代 + 年老代。

在这里插入图片描述

年轻代:Eden + 2*Survivor
年老代:OldGen
在jdk1.8中变化最大的Perm区,用Metaspace(元数据空间)进行了替换。

需要特别说明的是:Metaspace所占用的内存空间不是在虚拟机内部,而是在本地内存空间中,这也是与1.7的永久代最大的区别所在

在这里插入图片描述

垃圾回收基础

栈空间和堆空间

栈空间:方法结束,自动回收!

堆空间:需要手动管理回收!

程序中最难调试的BUG:野指针(空指针),并发问题

在这里插入图片描述

所以,Java为什么不让程序员来手动删除对象,明白不?上述的情况,可能会出现在比如:C语言,C++ 的语言场景中!

在这里插入图片描述

垃圾回收的语言发展

在C/C++语言中,没有自动垃圾回收机制,是通过new关键字申请内存资源,通过delete关键字释放内
存资源。如果,程序员在某些位置没有写delete进行释放,那么申请的对象将一直占用内存资源,最终
可能会导致内存溢出。

C / C++ 语言:

  • 手动管理
  • 忘记释放
  • 释放多次
  • 开发效率低

Java Python Go语言:

  • 自动管理
  • 引入GC Garbage Collector
  • 大大减低程序员门槛

应用程序只管分配,垃圾回收器负责回收!

如何定位垃圾

垃圾:没有引用指向的对象,就是垃圾对象!

如何找到垃圾?算法:引用计数法可达性分析方法

引用计数法

假设有一个对象A,任何一个对象对A的引用,那么对象A的引用计数器+1,当引用失败时,对象A的引用计数器就-1,如果对象A的计数器的值为0,就说明对象A没有引用了,可以被回收。

在这里插入图片描述

Python使用的较为多,但是,这种算法缺陷在于:无法解决循环引用的问题

在这里插入图片描述

public class A {
    public static void main(String[] args) {
        TestA a = new TestA();
        TestB b = new TestB();
        a.b = b;
        b.a = a;
        a = null;
        b = null;
        }
    }

class TestA {
    public TestB b;
}
class TestB {
    public TestA a;
}

优缺点

优点:

实时性较高,无需等到内存不够的时候,才开始回收,运行时根据对象的计数器是否为0,就可以直接回收。
在垃圾回收过程中,应用程序无需挂起。如果申请内存时,内存不足,则立刻报out of memery 错误。局部更新对象的计数器时,只是影响到该对象,不会扫描全部对象。

缺点:

每次对象被引用时,都需要去更新计数器,有一点时间开销。浪费CPU资源,即使内存够用,仍然在运行时进行计数器的统计。无法解决循环引用问题。(最大的缺点)

可达性分析方法

Java早期使用,但后期更喜欢采用:可达性分析方法

在这里插入图片描述

那什么是根呢?JVM线程栈,本地方法栈,运行时常量池,方法区的静态引用,类对象!

main()方法启动的哪些内容,就是根!

垃圾清除算法

标记-清除

标记-复制

标记-压缩

标记-清除

标记-清除算法:

在这里插入图片描述

但是这种算法:导致内存碎片化过于严重

优缺点

优点:

可以看到,标记清除算法解决了引用计数算法中的循环引用的问题,没有从root节点引用的对象都会被回收。

缺点:

效率较低,标记和清除两个动作都需要遍历所有的对象,并且在GC时,需要停止应用程序,对于交互性要求比较高的应用而言这个体验是非常差的。通过标记清除算法清理出来的内存,碎片化较为严重,因为被回收的对象可能存在于内存的各个角落,所以清理出来的内存是不连贯的。

标记-复制


标记-复制算法:将内存一分为二,一份专门用于复制!

在这里插入图片描述

但是这种算法:浪费内存


标记-压缩

标记-压缩算法:边清理,边压缩

在这里插入图片描述

但是这种算法:效率太低

三种算法都有问题,JVM采用三种的综合运用,产生了各种各样的GC垃圾回收器!

垃圾回收器

总览

随着内存大小不断变化,演变出越来越多的垃圾回收器!

在这里插入图片描述

分代模型:新生代1、老年代2

新生代:eden, 幸存区1,幸存区2 比例:8:1

在这里插入图片描述

在新生代,至少就可以做到90%的对象,都会被回收掉!

Minor-GC触发的时机:Eden满!

Full-GC触发的时机:Old满!

串行Serial 和 Serial-Old

在这里插入图片描述

Serial垃圾回收器:内存在几M - 几十M的场景下

Serial GC是一种单线程的垃圾回收器,它在一个单独的线程上运行,不会使用多个线程来进行垃圾回收,在回收的过程中,会停止所有业务线程(stop-the-world简称:stw),用于Minor-GC!算法:标记-复制算法

在这里插入图片描述

Serial-Old垃圾回收器

Serial-Old GC也是一种单线程的垃圾回收器,它在一个单独的线程上运行,不会使用多个线程来进行垃圾回收,在回收的过程中,会停止所有业务线程(stop-the-world简称:stw),用于Full-GC!算法:标记-清除算法、标记-压缩算法

并行Parallel (jdk1.8默认)

并行垃圾收集器在串行垃圾收集器的基础之上做了改进,将单线程改为了多线程进行垃圾回收,这样可以缩短垃圾回收的时间。(这里是指,并行能力较强的机器)当然了,并行垃圾收集器在收集的过程中也会暂停应用程序,这个和串行垃圾回收器是一样的,只是并行执行,速度更快些,暂停的时间更短一些。

在这里插入图片描述

Parallel垃圾回收器:内存在几十M - 几G的场景下

在这里插入图片描述

所以区别在于:Serial是单线程的,而Parallel是多线程并行的,房子大了,一个人忙不过来!

JDK1.8 默认采用的就是:Parallel 的组合 ps+po

java -XX:+PrintCommandLineFlags -version #在cmd中查看当前使用的GC回收器

在这里插入图片描述

JDK11使用G1

在这里插入图片描述

并发ParNew,CMS

当内存继续增大到 几十个G呢?多线程有时也不能解决根本问题了,是否是多线程越多越好呢?

Concurrent GC垃圾回收器:内存在几十G以上的场景下

在这里插入图片描述

Serial & Parallel 在GC时,都会打断业务线程,让业务线程停止(STW)

并发标记清除GC:意思是 GC回收线程 & 业务线程 可以并行处理!业务线程在产生垃圾,GC回收线程尽可能的让“业务线程”不需要STW的情况下,就可以及时回收业务线程所产生的垃圾!

在这里插入图片描述

尽可能少的STW,可以并行回收,这便是:Concurrent GC垃圾回收器最厉害的地方!

上述的图中,也只有 初始标记 & 重新标记 阶段,是需要STW的!


CMS全称 Concurrent Mark Sweep,是一款并行的、使用标记-清除算法的老年代垃圾回收器!

可以搭配Serial / ParNew 这些新生代的GC回收器使用!

在这里插入图片描述

初始标记,只标记Root上的根&根直接引用的对象,所以尽管采用STW,它的时间也不会太长!

重新标记,毕竟误标的对象,不会太多,所以STW的时间,也不会太长!

三色标记算法,发生在初始标记并发标记重新标记阶段,主要由3种颜色组成:黑,灰,白

黑:对象被标记,且它的所有子对象也被标记完

灰:对象被标记,但是它的子对象还没有被标记或标记完

白:对象没有被标记到,标记阶段结束后,会被当做垃圾回收掉

三色标记法

三色标记法的标记过程可以分为三个阶段:初始标记(Initial Marking)、并发标记(Concurrent Marking)和重新标记(Remark),

在这里插入图片描述

  • 初始标记:遍历所有的根对象,将根对象和直接引用的对象标记为灰色。在这个阶段中,垃圾回收器只会扫描被直接或者间接引用的对象,而不会扫描整个堆因此,初始标记阶段的时间比校短。(Stop The World)

  • 并发标记:在这个过程中,垃圾回收器会从灰色对像开始遍历整个对象图,将被引用的对像标记为灰色,并将己经遍历过的对象标记为黑色。并发标记过程中,应用程序线程可能会修改对家图,因此垃圾回收器需要便用写屏障(Write Barrier)技术来保证并发标记的正确性,(不需要STW)

  • 重新标记:重新标记的主要作用足标记在并发标记阶段中被修改的对象以及未被遍历到的对象。这个过程中,垃圾回收器会从灰色对象重新开始遍历对象图,将被引用的对家标记为灰色,并将已经遍历过的对象标记为黑色。(Stop The World)

在重新标记阶段结束之后,垃圾回收器会执行清除操作,将未被标记为可达对象的对象进行回收,从而释放内存空间,这个过程中,垃圾回收器会将所有未被标记的对象标记为白色(White)

三色标记算法的BUG:可能会产生多标,漏标的问题!漏标是最严重的问题,当然CMS & G1他们分别采用的解决方案也不一样!

多标:产生浮动垃圾,浮动垃圾情况不严重,下次GC线程直接回收就好!

在这里插入图片描述

漏标

在这里插入图片描述

CMS垃圾回收算法,在JDK1.8之后,就被干掉了!

CMS在增量更新阶段,会根据可达性分析算法,重头到尾扫描重新标记一次堆对象,所以STW时间将会非常的长!

Garbage FirstGC回收器

G1回收器,是当下的最为主流的垃圾回收器!

Garbage First 垃圾优先

G1垃圾回收器,抛弃了传统从物理上进行的分代算法,而采用分区region + 逻辑分代的算法!

G1(Garbage First)垃圾收集器是当今垃圾回收技术最前沿的成果之一。早在DK7就已加入JVM的收集器大家庭中,成为HotSpot重点发展的垃圾回收技术。同优秀的CMS垃圾回收器一样,G1也是关注最小时延的垃圾回收器,也同样适合大尺寸堆内存的垃圾收集,官方也推荐使用G1来代替选择CMS。G1最大的特点是引入分区的思路,弱化了分代的概念,合理利用垃圾收集各个周期的资源,解决了其他收集器甚至CMS的众多缺陷。

在这里插入图片描述

G1将Java堆划分为多个大小相等的独立区域(Region),JVM最多可以有2048个Region。 一般Region大小等于堆大小除以2048,比如堆大小为4096M,则Region大小为2M,当然也可以 用参数"-XX:G1HeapRegionSize"手动指定Region大小,但是推荐默认的计算方式。 G1保留了年轻代和老年代的概念,但不再是物理隔阂了,它们都是(可以不连续)Region的集合

默认年轻代对堆内存的占比是5%,如果堆大小为4096M,那么年轻代占据200MB左右的内存, 对应大概是100个Region,可以通过“-XX:G1NewSizePercent”设置新生代初始占比,在系统运行中,JVM会不停的给年轻代增加更多的Region,但是最多新生代的占比不会超过60%,可以 通过“-XX:G1MaxNewSizePercent”调整。年轻代中的Eden和Survivor对应的region也跟之前 一样,默认8:1:1,假设年轻代现在有1000个region,eden区对应800个,s0对应100个,s1对应100个。

一个Region可能之前是年轻代,如果Region进行了垃圾回收,之后可能又会变成老年代,也就是说Region的区域功能可能会动态变化。

G1垃圾收集器对于对象什么时候会转移到老年代跟之前讲过的原则一样,唯一不同的是对大对象的处理,G1有专门分配大对象的Region叫Humongous区,而不是让大对象直接进入老年代的 Region中。在G1中,大对象的判定规则就是一个大对象超过了一个Region大小的50%,比如按照上面算的,每个Region是2M,只要一个大对象超过了1M,就会被放入Humongous中,而且 一个大对象如果太大,可
能会横跨多个Region来存放。

Humongous区专门存放短期巨型对象,不用直接进老年代,可以节约老年代的空间,避免因为老年代空间不够的GC开销。 Full GC的时候除了收集年轻代和老年代之外,也会将Humongous区一并回收。

在这里插入图片描述

G1回收器,同样采用三色标记算法来完成 对象的标记,但是对于漏标的问题,它采用的解决方案是:原始快照

原始快照,GC线程在退出运行时,将所有灰色节点下的所有的引用,拍摄快照到Rset中;GC线程恢复后,直接使用快照数据;

“所有的灰色对家自己引用扫描完成之前册除了对白色对象的明引用”,这个条件如果被破坏了,那么就不会出现漏标的问题。所以:

如果灰色对象在扫描完成前到除了对白色对象的引用,那么我们就在灰色对象取消引用之前,先将灰色对象引用的白色对象记录下来在后续「重新标记] 阶段再以这些白色对象为根,对它的引用进行扫描,从而避免了漏标的问题。通过这种方式,原本漏标的对象就会被重新扫描变成灰色,从而变为存活状态。

但是这种方式可能会把本来真的要取消弱引用的对象给错的活了,从而产生浮垃级,但是就像前面说的,多标的问题是可以忽略的.

在jdk1.8用G1

ZGC(Oracle官方), Shenandoah(Redhat红帽) 这2种是:下一代的垃圾回收器(分页垃圾回收器),Epsilon 是空的回收器,主要用于开发JVM GC回收器的程序员Debug使用!

  • 在JDK1.7版本正式启用,移除了Experimental的标识,是JDK9以后的默认垃圾回收器,取代了CMs回收器以及Parallel+Parallel0ld组合。被Oracle官方称为全功能的垃圾收集器”。
  • 与此同时,CMS已经在JDK9中被标记为废弃(deprecated)。
  • G1在dk8中还不是默认的垃圾回收器,需要使用-XX:+UseG1GC来启用。

如果在jdk1.8用G1则:

java -jar -XX:+UseG1GC 某一个项目.jar

G1垃圾回收过程

G1垃圾回收3种模式:YoungGC、 Mixed GC和Full GC

G1GC的垃圾回收过程主要包括如下三个环节:

  • 年轻代GC(Young GC)
  • 老年代并发标记过程(Concurrent Marking)
  • 混合回收(Mixed GC)
  • Full GC(如果需要,单线程、独占式、高强度的Full GC还是继续存在的。它针对GC的评估失败提供了一种失败保护机制,即强力回收。)

在这里插入图片描述

顺时针,young gc一>young gc+concurrent mark一>Mixed GC)顺序,进行垃圾回收。

1.应用程序分配内存,当年轻代的Ed区用尽时开始年轻代回收过程:G1的年轻代收集阶段是一个并行的(多个回收线程)独占式(STW收集器。在年轻代回收期,G1GC暂停所有应用程序线程,启动多线程执行年轻代回收。然后从年轻代区间移动存活对象到Survivor区间或者老年区间,也有可能是两个区间都会涉及。

2.当堆内存使用达到一定值(默认45%)时,开始老年代并发标记过程

3.标记完成马.上开始混合回收过程。对于一个混合回收期,G1GC从老年区间移动存活对象到空闲区间,这些空闲区间也就成为了老年代的一部分。和年轻代不同,老年代的G1回收器和其他GC不同,G1的老年代回收器不需要整个老年代被回收,一次只需要扫描/回收一小部分老年代的Region就可以了。同时,这个老年代Region是和年轻代一起被回收的.

举个例子:一个web服务器,Java进程最大堆内存为4G,每分钟响应1500个请求,每45秒钟会新分配大约2G的内存。G1会每45秒钟进行一次年轻代回收,每31个小时整个堆的使用率会达到45%,会开始老年代并发标记过程,标记完成后开始四到五次的混合回收。

G1的四大特点

  • 并行与并发

    • ➢并行性: G1在回收期间,可以有多个Gc线程同时工作,有效利用多核计算能力。此时用户线程STW
    • ➢并发性: G1拥有与应用程序交替执行的能力,部分工作可以和应用程序同时执行,因此,一般来说,不会在整个回收阶段发生完全阻塞应用程序的情况
  • 分代收集

    • ➢从分代上看,G1依然属于分代型垃圾回收器,它会区分年轻代和老年代,年轻代依然有Eden区和Survivor区。但从堆的结构上看,它不要求整个Eden区、年轻代或者老年代都是连续的,也不再坚持固定大小和固定数量。
    • ➢将堆空间分为若干个区域(Region) ,这些区域中包含了逻辑上的年轻代和老年代。
    • ➢和之前的各类回收器不同,它同时兼顾年轻代和老年代。对比其他回收器,或者工作在年轻代,或者工作在老年代;
  • 空间整合

    • ➢CMS:“标记-清除”算法、内存碎片、若干次Gc后进行一次碎片整理
    • ➢G1将内存划分为一个个的region。 内存的回收是以region作为基本单位的。Region之间是复制算法。
    • 但整体上实际可看作是标记一压缩(Mark一Compact)算法,两种算法都可以避免内存碎片。
    • 这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。尤其是当Java堆非常大的时候,G1的优势更加明显
  • 可预测的停顿时间模型

    • ➢由于分区的原因,G1可以只选取部分区域进行内存回收,这样缩小了回收的范围,因此对于全局停顿情况的发生也能得到较好的控制。
    • ➢G1跟踪各个Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region。保证了G1 收集器在有限的时间内可以获取尽可能高的收集效率。
    • ➢相比于CMSGC,G1未必能做到CMS在最好情况下的延时停顿,但是最差情况也要好很多。

G1的适用场景

(1)面向服务端应用,针对具有大内存、多处理器的机器。(在普通大小的堆里表现并不惊喜)

最主要的应用是需要低GC延迟,并具有大堆的应用程序提供解决方案;
如:在堆大小约6GB或更大时,可预测的暂停时间可以低于0.5秒;(G1通过每次只清理部分而不是全部的Region的增量式清理来保证每次GC停顿时间不会过长)。

(2)用来替换掉JDK1.5中的CMS收集器;在下面的情况时,使用G1可能比CMS好:

①超过50%的Java堆被活动数据占用;
②对象分配频率或年代提升频率变化很大;
③GC停颅时间过长(长于0.5至1秒)。

HotSpot垃圾收集器里,除了G1以外,其他的垃圾收集器使用内置的JVM线程执行GC(线程优先级低)的多线程操作

而G1GC可以采用应用线程承担后台运行的GC工作,即当M的GC线程处理速度慢时,系统会调用应用程序线程帮助加速垃圾回收
过程。

垃圾回收器的使用

G1调优快速使用

最简单的使用G1调优3大步骤:

  1. 开启G1GC
  2. 设置堆的最大内存【防止内存抖动】
  3. 设置最大的停顿时间【单位毫秒】

简化设置:

java -jar -XX:+UseG1GC -Xms4g -Xmx4g -XX:MaxGCPauseMillis=200 某一个项目.jar

完整设置:

java -jar -XX:+UseG1GC -Xms4g -Xmx4g -XX:MaxGCPauseMillis=200 -XX:ParallelGCThreads=8 -XX:G1HeapRegionSize=16m -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=20 -XX:G1MaxNewSizePercent=40 -XX:TargetSurvivorRatio=50 -XX:MaxTenuringThreshold=15 -XX:InitiatingHeapOccupancyPercent=45 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/root/gc.log 某一个项目.jar

-Xms4g 设置初始堆的大小

-Xmx4g 设置最大堆的大小

-XX:+UnlockExperimentalVMOptions 解锁JVM额外参数

-XX:+PrintGCDetails -XX:+PrintGCDateStamps

-XX:+PrintGCTimeStamps -Xloggc:/root/gc.log 打印详细的 GC 日志,包括日期和时间戳,并将其写入指定的文件

在这里插入图片描述


8种GC回收器的比较

在这里插入图片描述

怎么选择GC回收器

怎么选择垃圾收集器?

1.优先调整堆的大小让JVM自适应完成。
2.如果内存小于100M,使用串行收集器
3.如果是单核、单机程序,并且没有停顿时间的要求,串行收集器
4.如果是多CPU、需要高吞吐量、允许停顿时间超过1秒,选择并行或者JVM自己选择
5.如果是多CPU、追求低停顿时间,需快速响应(比如延迟不能超过1秒,如互联网应用),使用并发收集器

官方推荐G1,性能高。现在互联网的项目,基本都是使用G1。


总结

1.JVM的内存模型,对比了1.7和1.8的内存模型的变化;
2.垃圾回收的语言发展;定位垃圾的方法,引用计数法和可达性分析发以及垃圾清除算法;
3.Java中的垃圾回收器,由串行、到并行再到并发,最后到G1的演变;
4.垃圾回收器的对比和使用指引。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于指数分布算法的无人机航迹规划-附代码

基于指数分布算法的无人机航迹规划 文章目录 基于指数分布算法的无人机航迹规划1.指数分布搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要:本文主要介绍利用指数分布算法来优化无人机航迹规划。 …

阿里云服务器密码在哪查看?如何设置修改初始密码?

阿里云服务器创建后没有默认初始密码,需要用户通过重置实例密码的方式来设置新的密码,阿里云服务器网aliyunfuwuqi.com分享阿里云服务器ECS重置实例密码的详细操作流程: 阿里云服务器重置密码方法 1、登录到阿里云服务器管理控制台 2、左侧…

乐园要吸引儿童还是家长?万达宝贝王2000万会员的求精之路

2023年6月,万达宝贝王正式迈入“400店时代”。 万达宝贝王在全国200多座城市,以游乐设施、主题活动、成长课程服务10亿多用户,拥有2000多万名会员,是真正的国内儿童乐园领跑者。 当流量时代变成“留量”时代,用户增长…

按键精灵中的UI界面操作

1. 按键精灵中UI界面常用的控件 1. 文字框 界面1: {标签页1:{文字框:{名称:"文字框1",显示内容:"显示内容",文字大小:0,高度:0,宽度:0,注释:"文字大小、高度、宽度是可选属性,如需使用默认值,可保持值为0或直接删除此属性&qu…

汽车制造业,通常都穿用哪些防护功能的劳保鞋呢?

近年来汽车行业发展迅速,各家各户有条件的话都会买车,汽车已经成为人们主要出行工具。随着人们生活水平的提高,汽车市场需求持续增长,现在的汽车制造厂也是越来越多,使得汽车制造业成为机械行业的重要支柱之一。 那么对…

【深度学习】可交互讲解图神经网络GNN

在正式开始前,先找准图神经网络GNN(Graph Neural Network)的位置。 图神经网络GNN是深度学习的一个分支。 深度学习的四个分支对应了四种常见的数据格式,前馈神经网络FNN处理表格数据,表格数据可以是特征向量,卷积神经网络CNN处理…

Spark大数据应用实战

系列文章目录 送书第一期 《用户画像:平台构建与业务实践》 送书活动之抽奖工具的打造 《获取博客评论用户抽取幸运中奖者》 送书第二期 《Spring Cloud Alibaba核心技术与实战案例》 送书第三期 《深入浅出Java虚拟机》 送书第四期 《AI时代项目经理成长之道》 …

昇腾CANN 7.0 黑科技:DVPP硬件加速训练数据预处理,友好解决Host CPU预处理瓶颈

在NPU/GPU上进行模型训练计算,为了充分使用计算资源,一般采用批量数据处理方式,因此一般情况下为提升整体吞吐率,batch值会设置的比较大,常见的batch数为256/512,这样一来,对数据预处理处理速度…

第十五章,输入输出流代码

package 例题;import java.io.File;public class 例题1 {public static void main(String[] args) {//创建文件对象File file new File("D:\\Java15-1.docx");//判断,如果该文件存在。exists存在的意思if (file.exists()) {//删除//file.delete();//Syst…

Modbus协议简介及模拟环境搭建

Modbus协议是一种已广泛应用于当今工业控制领域的通用通讯协议,Modbus 是MODICON公司(现为施耐德电气公司的一个品牌)最先倡导的一种软的通讯规约。 通过此协议,控制器相互之间、或控制器经由网络(如以太网)可以和其它设备之间进…

【JavaEE】HTTP协议(什么是HTTP?、HTTP格式、form表单和ajax构造HTTP)

一、什么是HTTP协议? 1.1 HTTP (全称为 “超文本传输协议”) 是一种应用非常广泛的 应用层协议 1.2 理解HTTP协议的工作过程 当我们在浏览器中输入一个 “网址”, 此时浏览器就会给对应的服务器发送一个 HTTP 请求. 对方服务器收到这个请求之后, 经过计算处理, 就…

Python基础入门----Python模块和包:导入模块、创建自己的模块和包

文章目录 Python模块和包:导入模块、创建自己的模块和包导入模块创建自己的模块创建包使用相对导入Python模块和包:导入模块、创建自己的模块和包 Python是一种功能强大的编程语言,它的模块和包系统是其强大功能的基石之一。在Python中,模块是包含Python定义和声明的文件。…

新功能案例分享丨DolphinDB 与你相约上海,报名限时开放!

这一次 D-Day 系列活动来到了上海,DolphinDB 将联合华金证券,以 “ DolphinDB 新功能及私募行业案例分享” 为主题,为大家带来一场精彩的线下主题交流。快点击链接报名本次活动吧~ 活动时间:11月16日下午13:30 活动地点&#xf…

出口美国操作要点汇总│走美国海运拼箱的注意事项│箱讯科技

01服务标准 美国的货物需要细致的服务,货物到港后的服务也是非常重要的。如果在货物到港15天内,如果没有报关行进行(PROCEED),货物就会进入了G.O.仓库,G.O.仓库的收费标准是非常高的。 02代理资格审核 美国航线除了各家船公司&a…

深入理解 Django 模板系统

概要 在任何 Web 开发过程中,渲染和展示数据是不可或缺的一部分。Django 作为一个高效的 Python Web 框架,提供了一个强大且灵活的模板系统。本文将详细介绍 Django 模板系统的核心概念、语法和高级功能。 一、Django 模板系统简介 Django 的模板系统允…

机器视觉人体跌倒检测系统 - opencv python 计算机竞赛

0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 机器视觉人体跌倒检测系统 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数&…

商人宝:网页收银软件有哪些功能

网页收银软件凭借无需安装、无需手工升级以及良好的用户体验等优势迅速发展并替代传统收银软件,今天商人宝为大家分享网页收银软件一般有哪些功能。欢迎大家点赞关注,以及收藏本文章,以便后续多看多了解。 1、快速收银 通过扫码枪快速将商品加…

代码随想录算法训练营第16天|104. 二叉树的最大深度111.二叉树的最小深度222.完全二叉树的节点个数

JAVA代码编写 104. 二叉树的最大深度 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:3示例 2: …

2023年下半年信息系统项目管理师下午真题及答案解析(第三批)

试题一(6分) 项目有A、B、C、D、E、F 6个活动,各活动的关系如下表: 2023年下半年信息系统项目管理师下午真题答案及解析 试题一(6分)

xshell和linux什么关系,其实很简单

如果你是从事网络安全相关的工作人员,那你一定对很多人xshell和linux这两词很熟悉,那么xshell和linux究竟是什么关系呢?今天就让小编给你详细讲讲。 xshell和linux什么关系 一、xshell和linux什么关系 Xsehll是一款在Windows平台上运行的远…
最新文章