JVM 与 GC 讲解

2023-10-27

一、概述

  • JVM(Java Virtual Machine)是一种在计算机上运行Java字节码的虚拟机。它允许Java程序在不同的操作系统上具有跨平台的能力,因为它提供了一个统一的运行环境。JVM 负责将Java源代码编译成字节码,然后在运行时解释执行或者编译执行这些字节码。

  • GC(Garbage Collection)是JVM的一个重要功能,用于自动管理内存。在Java中,开发人员不需要手动分配和释放内存,因为 GC 负责监测内存中不再使用的对象,并将它们自动回收以释放内存资源。这样可以减少内存泄漏和程序崩溃的风险,但同时也会引入一些性能开销。

GC 有不同的实现方式,其中两种主要的策略是:

  • 标记-清除(Mark and Sweep):这是最基本的垃圾回收算法。它首先标记所有仍然被引用的对象,然后清除那些没有被标记的对象,从而释放其占用的内存空间。这种方法可能导致内存碎片化问题,从而影响程序性能。

  • 分代垃圾回收(Generational Garbage Collection):根据对象的生命周期将内存分为不同的代(Generation),一般分为年轻代(Young Generation)老年代(Old Generation)。大多数对象在短时间内就会变成垃圾,所以年轻代采用较短周期的GC策略,而老年代则采用更长周期的策略。常见的分代垃圾回收算法是G1(Garbage-First)垃圾回收器。

JVMGC 对应用程序性能有着重要影响。频繁的 GC 事件可能导致应用程序的暂停时间增加,从而降低用户体验。为了优化 GC 性能,开发人员可以采取以下措施:

  • 选择合适的GC算法和回收器:根据应用程序的性质和需求,选择适合的GC算法和回收器,如Serial GCParallel GCConcurrent Mark-Sweep(CMS)GCG1 GC等。

  • 调整堆内存大小:适当设置堆内存大小,避免过大或过小的堆对性能产生负面影响。

  • 避免创建过多临时对象:过多的临时对象会导致频繁的GC事件。可以重用对象或者使用对象池来减少临时对象的创建。

  • 优化对象的生命周期:尽量使对象的生命周期与其实际使用时间相符,避免长时间存活的对象进入年轻代,从而减少老年代的压力。

  • 监控和调优:使用 JVM 性能分析工具来监控 GC 事件,找出性能瓶颈并进行调优。

总之,理解 JVMGC 的工作原理对于编写高性能、稳定的Java应用程序至关重要。

二、JVM 内存模型


Java虚拟机(JVM)内存模型定义了Java程序在运行时如何使用计算机的内存资源。它将内存划分为不同的区域,每个区域用于存储不同类型的数据和执行不同的任务。以下是JVM内存模型的主要部分:

  • 方法区(Method Area):方法区是一个用于存储类结构信息、常量、静态变量、即时编译器编译后的代码等的区域。它在JVM启动时被创建,并且对于每个类加载器只存在一个方法区。在较早的JVM版本中,方法区被称为“永久代”(Permanent Generation,但在Java 8及以后的版本中,永久代被移除,而是用元空间Metaspace)取代。

  • 堆(Heap):堆是Java程序运行时对象的主要存储区域。它被用来存储各种对象实例,包括用户自定义对象以及运行时创建的对象。堆被划分为新生代(Young Generation)和老年代(Old Generation)。新生代主要用于存放新创建的对象,老年代用于存放生命周期较长的对象。

  • 新生代:新生代又被划分为Eden空间和两个Survivor空间(通常称为S0S1)。新创建的对象首先被分配到Eden空间,经过一些垃圾回收操作后,仍然存活的对象会被移动到Survivor空间,然后经过多次垃圾回收后,仍然存活的对象会被晋升到老年代。
    老年代:老年代主要用于存放经过多次垃圾回收仍然存活的对象,这些对象的生命周期较长。

  • 栈(Stack):栈被用来存储线程的局部变量、方法调用和返回信息。每个线程都有自己的栈空间,栈中的数据存储在栈帧中,每个方法调用会创建一个新的栈帧。栈是一个后进先出(LIFO)的数据结构。

  • 本地方法栈(Native Method Stack):本地方法栈与栈类似,但是它用于存储Java方法调用本地方法(用其他语言编写的方法)时的信息。

  • 程序计数器(Program Counter):每个线程都有一个程序计数器,它保存着线程正在执行的JVM指令的地址。在线程切换时,程序计数器的值会更新到新线程的执行位置。

  • 直接内存(Direct Memory):直接内存并不是JVM运行时数据区的一部分,但它与Java NIO(New I/O)相关。直接内存是通过ByteBuffer等NIO类分配的,实际上是在堆之外的内存,但是它由JVM管理。

JVM内存模型的理解对于编写高效且稳定的Java应用程序至关重要。通过对不同内存区域的管理和优化,可以提高应用程序的性能和可靠性。

三、GC算法和回收器

在Java虚拟机(JVM)中,垃圾回收(GC)是自动管理内存的机制,而垃圾回收涉及两个主要方面:垃圾回收算法垃圾回收器。垃圾回收算法定义了如何判断哪些对象是垃圾以及如何回收它们,而垃圾回收器是实际执行垃圾回收算法的组件。

以下是一些常见的垃圾回收算法和垃圾回收器:

1)垃圾回收算法

  • 标记-清除(Mark and Sweep)算法

    1. 首先,标记阶段标记所有可达的对象。
    2. 然后,清除阶段将未被标记的对象回收,释放内存空间。
  • 标记-整理(Mark and Compact)算法

    1. 标记阶段与标记-清除算法相同,标记所有可达对象。
    2. 整理阶段将存活的对象移动到一侧,然后释放未被移动的内存。
  • 复制(Copying)算法

    1. 将内存分为两个区域,通常是Eden和Survivor空间。
    2. 在每次垃圾回收时,将存活的对象从一个区域复制到另一个区域,然后清除原区域。
  • 增量式和并发式算法

    1. 增量式垃圾回收:将垃圾回收过程分成多个阶段,在应用程序执行期间交替执行,减少停顿时间。
    2. 并发式垃圾回收:允许在应用程序执行时进行垃圾回收,从而减少停顿时间。

2)垃圾回收器

  • Serial 回收器

    1. 单线程垃圾回收器,主要用于新生代。
    2. 使用复制算法进行垃圾回收。
  • Parallel 回收器

    1. 多线程垃圾回收器,适用于多核处理器。
    2. 主要用于新生代,使用复制算法。
  • CMS(Concurrent Mark-Sweep)回收器

    1. 并发垃圾回收器,用于老年代。
    2. 标记-清除算法,允许在应用程序执行时部分并发执行。
  • G1(Garbage-First)回收器

    1. 面向大堆和低停顿时间的垃圾回收器。
    2. 使用标记-整理算法,将内存划分为多个区域,优先回收包含垃圾最多的区域。
  • ZGC和Shenandoah

    1. 最小化停顿时间的垃圾回收器,适用于大堆。
    2. 使用不同的算法和技术来实现低停顿时间的垃圾回收。

每种垃圾回收算法和垃圾回收器都有其适用的场景和性能特点。选择适当的垃圾回收器取决于应用程序的需求,内存使用情况和性能目标。

四、垃圾回收机制(GC)

在这里插入图片描述

Java垃圾回收机制是一种自动管理内存的机制,由Java虚拟机(JVM)负责。它的目标是通过检测和回收不再被程序引用的对象,释放内存并防止内存泄漏。以下是Java垃圾回收机制的主要特点:

  • 可达性分析:Java的垃圾回收机制基于可达性分析。JVM会从一组根对象(如全局变量、静态变量、活跃线程的局部变量等)开始,逐步遍历对象之间的引用关系,找到所有可达的对象。那些不可达的对象被认为是垃圾,可以被垃圾回收器回收。

  • 分代垃圾回收:Java的垃圾回收采用了分代回收策略。内存被分为新生代(Young Generation)老年代(Old Generation)。新创建的对象通常会分配在新生代,而生命周期较长的对象则晋升到老年代。不同代使用不同的垃圾回收算法。

  • 新生代垃圾回收:新生代内存被划分为Eden空间和两个Survivor空间(通常称为S0S1)。通常使用复制算法,在新生代之间来回复制存活的对象。经过多次回收后仍然存活的对象会被晋升到老年代。

  • 老年代垃圾回收:老年代内存通常存放着生命周期较长的对象。老年代的回收算法包括标记-整理(Mark and Compact)标记-清除(Mark and Sweep)

  • 并发和并行垃圾回收:一些JVM实现支持并发(Concurrent)垃圾回收和并行(Parallel)垃圾回收。并发垃圾回收允许在应用程序执行时进行部分垃圾回收,以减少停顿时间。并行垃圾回收使用多个线程并行执行垃圾回收操作,以提高回收效率。

  • G1垃圾回收器Java 7引入了G1(Garbage-First)垃圾回收器,它是一种面向大堆、高吞吐量和低停顿时间的垃圾回收器。G1将内存划分为不同的区域,并优先回收包含垃圾最多的区域,从而最大限度地减少停顿时间。

  • 元空间:在Java 8及以后的版本中,永久代被移除,而是用元空间Metaspace)来管理类的元数据和静态变量。元空间不再受到固定大小的限制,可以根据应用程序的需求动态调整。

1)分代垃圾回收机制

分代垃圾回收机制是一种内存管理策略,主要用于优化垃圾回收的效率。它的核心思想是将内存划分为不同的代(Generation),通常包括新生代(Young Generation)和老年代(Old Generation),以便更有效地管理不同生命周期的对象。
在这里插入图片描述
以下是分代垃圾回收机制的原理:

  • 新生代(Young Generation)

    • 新生代主要用于分配新创建的对象。由于大部分对象的生命周期很短,新生代采用了一种高效的垃圾回收算法,通常是复制算法(Copying Algorithm)

    • 新生代被分为三个部分:Eden空间两个Survivor空间(通常称为S0和S1)。新创建的对象首先分配在Eden空间。

    • 在垃圾回收过程中,首先会将Eden空间和一个Survivor空间中仍然存活的对象复制到另一个Survivor空间中,然后清除Eden和前一个Survivor空间中的所有对象。这样,每次垃圾回收后,存活的对象仍然保留在新生代。

  • 晋升与老年代(Promotion and Old Generation)

    • 在经过多次新生代的垃圾回收后,仍然存活的对象会被晋升到老年代。晋升的条件通常包括对象的年龄(在Survivor空间中的次数)和老年代的空间大小等。
    • 老年代主要用于存放生命周期较长的对象,因此老年代的垃圾回收策略通常使用标记-整理Mark and Compact)或标记-清除Mark and Sweep)算法。
  • 分代切换

    • 分代垃圾回收通过合理地将对象在不同代之间进行切换,将不同生命周期的对象分配到适当的内存区域。
    • 新对象首先分配在新生代,然后通过多次垃圾回收判断其是否仍然存活。如果存活,它会被晋升到老年代,而不再频繁地在新生代进行垃圾回收。

分代垃圾回收机制的原理是根据对象的生命周期特点,将不同生命周期的对象放置在不同的内存区域,并使用不同的垃圾回收策略,从而提高了垃圾回收的效率和性能。这种机制在处理短寿命对象和长寿命对象的应用中具有优势。

2)G1 垃圾回收器

G1(Garbage-First)收集器是Java虚拟机(JVM)中的一种垃圾回收器,旨在提供更高吞吐量和更稳定的停顿时间。它于JDK 7引入,主要针对大内存堆和低停顿时间的应用场景。G1收集器通过将堆内存划分为多个区域(Region)来管理内存,并采用不同的垃圾回收策略来实现其目标。

以下是G1收集器的一些特点和工作原理:

  • 区域划分G1 将堆内存划分为多个大小相等的区域,每个区域通常是1MB32MB的大小。这些区域可以是 Eden 区、Survivor 区或老年区。

  • Mixed GCG1 收集器使用 Mixed GC 策略,它综合了新生代和老年代的垃圾回收策略。在每次垃圾回收时,G1 会根据当前垃圾回收的需求来选择要回收的区域,优先选择包含垃圾最多的区域进行回收。

  • 并发标记G1 采用并发标记算法,允许在应用程序执行时进行标记阶段。这有助于减少垃圾回收造成的停顿时间。标记阶段将标记所有存活的对象,以便在后续的垃圾回收阶段进行回收。

  • 整理阶段G1 使用标记-整理(Mark and Compact)算法来进行垃圾回收,以减少碎片。在回收过程中,G1 会将存活对象移动到堆的一侧,然后清除未被移动的区域。

  • Region之间的引用G1 会跟踪Region 之间的引用关系,以帮助确定存活对象的引用链。这有助于在回收时快速找到存活的对象。

  • 停顿时间目标G1 的一个主要目标是控制垃圾回收造成的停顿时间。它会根据用户设置的停顿时间目标来调整垃圾回收的频率和区域的选择,以尽量减少长时间的停顿。

G1 收集器在大堆内存和低停顿时间的应用场景下表现出色。它通过区域划分、并发标记和 Mixed GC等策略,减少了垃圾回收带来的长时间停顿,同时提供了相对较高的吞吐量。根据应用程序的需求和性能目标,选择适当的垃圾回收器非常重要,G1 是一个在这方面具有竞争力的选择。

3)FullGC 机制

Full GC(Full Garbage Collection) 是指对整个堆内存(包括新生代老年代)进行垃圾回收的操作,它的执行会导致应用程序的停顿时间较长。相对而言,Full GC 的停顿时间通常比部分垃圾回收(如新生代的垃圾回收)要长,因为它需要处理整个堆内存中的对象。

在这里插入图片描述

Full GC 通常会在以下情况下发生:

  • 内存不足:当堆内存中的对象数量增加,达到了堆内存的容量上限,就会触发Full GC,以尝试释放更多的内存空间。

  • 长时间运行后:长时间运行的Java应用程序可能会导致老年代中的对象堆积,最终触发Full GC,以清理老年代中的垃圾对象。

  • 显式调用:开发人员可以通过Java代码中的System.gc()方法显式调用垃圾回收,其中可能会包括Full GC操作。

Full GC执行的过程通常包括以下步骤:

在这里插入图片描述

  • 标记阶段:标记所有存活的对象,包括新生代和老年代中的对象。

  • 整理阶段:对老年代中的存活对象进行整理,以减少内存碎片。

  • 回收阶段:回收所有未被标记的对象,释放内存空间。

Full GC 的停顿时间较长,可能会对应用程序的性能和响应时间产生影响。因此,在设计和优化Java应用程序时,需要根据应用的需求和性能目标,合理配置堆内存大小、垃圾回收策略以及选择合适的垃圾回收器,以尽量减少Full GC的发生和影响。


JVM 与 GC 讲解就先到这里了,有任何疑问请关注我公众号:大数据与云原生技术分享,进行技术交流,如本篇文章对您有所帮助,麻烦帮忙一键三连(点赞、转发、收藏)~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JVM 与 GC 讲解 的相关文章

  • 在最近的 JVM 中,不可见引用仍然是一个问题吗?

    我正在读书Java 平台性能 http java sun com docs books performance 1st edition html JPAppGC fm html 遗憾的是 自从我最初提出这个问题以来 该链接似乎已经从互联网上
  • G1 GC 单个、非常长的年轻 GC 发生且 ParallelGCThreads=1

    I set ParallelGCThreads 1并使用G1 GC 所有其他JVM设置为默认设置 我跑PageRank在 Spark 1 5 1 上 有两个 EC2 节点 每个节点有 100 GB 堆 我的堆使用情况图如下 红色区域 年轻代
  • JVM 内存类型

    我正在做一个监控项目 我们有监控软件正在运行并从服务器重新收集指标 一切工作正常 但我们需要一些有关 JVM 内存使用情况详细信息 我们有一些具有不同内存类型的列 我们需要知道这些是什么 Heap Non Heap Usage Peak C
  • 为什么要实现finalize()?

    我已经阅读了很多 Java 新手问题finalize 令人困惑的是 没有人真正明确表示 Finalize 是一种不可靠的清理资源的方法 我看到有人评论说他们用它来清理连接 这真的很可怕 因为接近保证连接关闭的唯一方法是最后实现 try ca
  • 病毒或机器故障导致“无法创建Java虚拟机”?

    我用的是双核XP机安装了 4GB 内存 但仅2 5GB由于 32 位事实 由操作系统报告 我正在积极修改旧的 JAVA 应用程序至少一个月 使用最新的Eclipse 编辑 构建和运行 和Ant 另一种构建和运行的方式 在里面Eclipse运
  • 将 JVM 字节码往返于文本表示的故障安全方法

    我正在寻找一种在 JVM 类文件和文本表示之间往返的故障安全方法 一项严格的要求是 只要文本表示形式保持不变 生成的往返 JVM 类文件在功能上与原始 JVM 类文件完全相同 此外 文本表示必须是人类可读和可编辑的 应该可以对文本表示进行小
  • JVM 规范更新

    JVM 规范第 2 版的日期是 1999 年 自那时以来 我应该考虑学习哪些重要更新 如动态调用 这当然是为了了解现代 JVM 实现的内部原理 特别是 HotSpot 访问此链接http wikis sun com display HotS
  • Lambda 性能改进,Java 8 与 11

    我对 lambda 与方法参考运行了一些 JMH 测试 看起来类似于 IntStream reduce Integer max vs IntSream reduce i1 i2 gt Integer max i1 i2 我注意到 在 Jav
  • 估计 64 位 Java 中最大安全 JVM 堆大小

    在分析存在一些问题的 64 位 Java 应用程序的过程中 我注意到分析器本身 YourKit 正在使用真正大量的内存 我在 YourKit 启动脚本中得到的是 JAVA HEAP LIMIT Xmx3072m XX PermSize 25
  • 热点 JVM 字节码解释器是跟踪 JIT 吗?

    这个问题几乎说明了一切 我一直在寻找答案 甚至通过 VM 规范 但我没有明确说明 No 不过 还有一些其他 JVM 具有跟踪 JIT HotPath http HotPath GoogleCode Com and Maxine http L
  • 为什么 JVM 同时具有“invokespecial”和“invokestatic”操作码?

    两条指令都使用静态而不是动态调度 似乎唯一的实质性区别是invokespecial始终将一个对象作为其第一个参数 该对象是分派方法所属类的实例 然而 invokespecial实际上并没有把物体放在那里 编译器负责通过在发出之前发出适当的堆
  • 如何计算Java数组的内存大小?

    我知道如何通过添加三个部分来计算Java对象的内存大小 标头 属性 引用 我还知道Java数组也是一个对象 但是当我读到 Understanding the JVM Advanced Features and Best Practices
  • Java 中的引用变量里面有什么?

    我们知道对象引用变量保存表示访问对象的方式的位 它不保存对象本身 但保存诸如指针或地址之类的东西 我正在阅读 Head First Java 第 2 版 一书 书中写道 第 3 章第 54 页 在 Java 中我们并不真正知道什么是 在引用
  • Oracle 的商业 Hotspot JVM 相对于 OpenJDK 有哪些性能优势?

    正如这个问题中所描述的 OpenJDK 与 Java HotspotVM https stackoverflow com q 44335605 1593077 Oracle 的商业 Hotspot JVM 本质上是 OpenJDK 加上一些
  • 为什么不在下一个 JVM 中删除类型擦除呢?

    Java 在 Java 5 中引入了泛型类型擦除 因此它们可以在旧版本的 Java 上运行 这是兼容性的权衡 我们已经失去了这种兼容性 1 https stackoverflow com questions 22610400 a progr
  • Scala 对大数的阶乘有时会崩溃,有时不会

    以下程序经过编译和测试 有时返回结果 有时充满屏幕 java lang StackOverflowError at scala BigInt apply BigInt scala 47 at scala BigInt equals BigI
  • 如何判断我是在 64 位 JVM 还是 32 位 JVM 中运行(在程序内)?

    如何判断应用程序运行的 JVM 是 32 位还是 64 位 具体来说 我可以使用哪些函数或属性来在程序中检测到这一点 对于某些版本的 Java 您可以使用标志从命令行检查 JVM 的位数 d32 and d64 java help d32
  • Java GuardedString - 用于加密的随机密钥是否存储在 Java 堆内存中?如果不是,那么密钥保存在哪里?

    Oracle 的 org identityconnectors common security GuardedString 要转换为 GuardedString 的原始数据需要由 EncryptorImpl class 随机生成的加密密钥
  • 为什么 MetaSpace 大小是已用 MetaSpace 的两倍?

    我写了一个程序来模拟MetaSpace OOM 但我发现MetaSpace Size几乎总是两倍大Used MetaSpace Why 我用标志运行我的程序 XX MaxMetaspaceSize 50m 程序抛出OOM时Used Meta
  • Java的-XX:+UseMembar参数是什么

    我在各种地方 论坛等 看到这个参数 并且常见的答案是它有助于高并发服务器 尽管如此 我还是找不到 sun 的官方文档来解释它的作用 另外 它是Java 6中添加的还是Java 5中存在的 顺便说一句 许多热点虚拟机参数的好地方是这一页 ht

随机推荐

  • 基于stm32作品设计:多功能氛围灯、手机APP无线控制ws2812,MCU无线升级程序

    文章目录 一 作品背景 二 功能设计与实现过程 三 实现基础功能 一 首先是要选材 二 原理图设计 二 第一版本PCB设计 三 焊接PCB板 四 编写单片机程序 五 下载程序验证 四 外壳设计 一 CAD图纸设计 二 磨砂亚克力板 五 重新
  • [Git] 代码管理之 Git(六)Git rebase 压缩提交历史

    我们在工作中 可能会出现这样的情况 一项工作由好几个同事同时完成 然后每个人针对当前的feature都有对应的提交 那么就会造成同一个feature有多次提交的这样的冗余存在 除此之外 如果我们自己针对同一个feature的每天的提交以及一
  • JVM(六)方法调用(补充知识)

    方法调用并不等同于方法中的代码被执行 方法调用阶段唯一的任务就是确定被调用方法的版本 即调用哪一个方法 暂时还未涉及方法内部的具体运行过程 一切方法调用在Class文件里面存储的都只是符号引用 而不是方法在实际运行时内存布局中的入口地址 也
  • 关于H264相关的EBSP,RBSP,SODP的说明

    1 关于H264相关的EBSP RBSP SODP的说明 1 EBSP 扩展字节序列载荷 Encapsulated Byte Sequence Payload 它去掉了00 00 01 00 00 00 01这些起始码 但包含了0x3防止竞
  • 时序约束优先级_静态时序分析圣经翻译计划——附录A:SDC

    本附录将介绍1 7版本的SDC格式 此格式主要用于指定设计的时序约束 它不包含任何特定工具的命令 例如链接 link 和编译 compile 它是一个文本文件 可以手写或由程序创建 并由程序读取 某些SDC命令仅适用于实现 implemen
  • @Around简单使用示例——SpringAOP增强处理

    Around的作用 既可以在目标方法之前织入增强动作 也可以在执行目标方法之后织入增强动作 可以决定目标方法在什么时候执行 如何执行 甚至可以完全阻止目标目标方法的执行 可以改变执行目标方法的参数值 也可以改变执行目标方法之后的返回值 当需
  • 如何搭建Spring开发环境呢?

    转自 如何搭建Spring开发环境呢 下文讲述搭建Spring开发环境的方法分享 如下所示 由于Spring是基于Java代码的一个框架 所以在Spring环境搭建之前 我们需为开发环境安装好 JDK Java开发环境 Eclipse Ja
  • 来自ebay内部的「软件测试」学习资料,覆盖GUI、API自动化、代码级测试及性能测试等,Python等,拿走不谢!...

    在软件测试领域从业蛮久了 常有人会问我 刚入测试一年 很迷茫 觉得没啥好做的 测试在公司真的不受重视 我是不是去转型做开发会更好 资深的测试架构师的发展路径是怎么样的 我平时该怎么学习 我估计不少人有这样的想法 甚至你也会被身边的人所影响
  • React 中constructor 作用

    React 中constructor 作用 react中的constructor大体有两个作用 1 初始化this state 2 纠正方法的this的指向 constructor props super props this state
  • 大数据毕设 python+深度学习+opencv实现植物识别算法系统

    文章目录 0 前言 2 相关技术 2 1 VGG Net模型 2 2 VGG Net在植物识别的优势 1 卷积核 池化核大小固定 2 特征提取更全面 3 网络训练误差收敛速度较快 3 VGG Net的搭建 3 1 Tornado简介 1 优
  • LWIP学习笔记(2)---IP协议实现细节

    IP头 收到的数据首先保存在pbuf结构中 The IPv4 header struct ip hdr version header length PACK STRUCT FLD 8 u8 t v hl type of service PA
  • C++11线程库 (六) 条件变量 Condition variables

    一 什么是条件变量 条件变量类 condition variable 是一个同步原语 它可以在同一时间阻塞一个线程或者多个线程 直到其他线程改变了共享变量 条件 并通知 primitive 原语 表达的是基础 基本的 是其他复杂应用的构建基
  • 基于高德地图的描点操作,监听地图缩放,展示合理数量的marker

    1 根据两点经纬度算两点之间的距离函数 function Rad d return d Math PI 180 0 经纬度转换成三角函数中度分表形式 计算距离 参数分别为第一点的纬度 经度 第二点的纬度 经度 function GetDis
  • java缓存面试问题_分布式缓存的面试题5

    1 面试题 如何保证Redis的高并发和高可用 redis的主从复制原理能介绍一下么 redis的哨兵原理能介绍一下么 2 面试官心里分析 其实问这个问题 主要是考考你 redis单机能承载多高并发 如果单机扛不住如何扩容抗更多的并发 re
  • R语言数据输入

    一 使用键盘输入数据 在导入数据比较少的时候 我们使用这种方法 R中的函数 edit 会自动调用一个允许手动输入数据的文本编辑器 具体步骤如下 1 创建一个空数据框 或矩阵 其中变量名和变量的模式需与理想中的最终数据集一致 2 针对这个数据
  • java使用aspose将word,excel,ppt转pdf

    1 测试环境springboot jdk1 8 aspose cells 8 5 2 jar 用于转换xls aspose words 16 8 0 jdk16 jar 用于转换doc 2 所用jar 签名百度网盘地址 链接 https p
  • Pytorch加载自己的数据集(以图片格式的Mnist数据集为例)

    文章目录 Pytorch加载自己的数据集 以图片格式的Mnist数据集为例 前言 一 数据集转换 二 构建自己的数据集 1 引入库 2 构建MnistDataset类 3 搭建网络模型 三 完整代码 总结 Pytorch加载自己的数据集 以
  • 【最新更新】2020研究生华为杯数学建模比赛题目+题目分析【持续更新】

    各参赛队伍 为了保证2020年 华为杯 第十七届中国研究生数学建模竞赛顺利举行 现将竞赛开赛的相关事项通知如下 一 时间节点 1 加密题目开始下载时间 2020年9月16日8 00 截止时间 2020年9月20日17 00 2 题目解密密码
  • 强化学习 OpenAI Gym Universe Docker在Windows WSL 2安装配置最全的全记录

    1 事情的起源 全记录事情的起源是为了学习Python强化学习实战 先在自己的windows操作系统的Pycharm Anaconda Gym配置下运行成功了CartPole示例和CarRacing示例 接着运行Universe 据说Ope
  • JVM 与 GC 讲解

    文章目录 一 概述 二 JVM 内存模型 三 GC算法和回收器 1 垃圾回收算法 2 垃圾回收器 四 垃圾回收机制 GC 1 分代垃圾回收机制 2 G1 垃圾回收器 3 FullGC 机制 一 概述 JVM Java Virtual Mac