从0开始回顾JVM---系列三

简介: 20、有哪几种垃圾回收器,各自的优缺点是什么? ⚡ 垃圾回收器主要分为以下几种:Serial,Parallel,CMS,G1。1. Serial● 单线程垃圾回收器,该线程运行时,其他线程都暂停,使用复制算法; ● 使用场景: 堆内存较小,适合个人电脑(CPU核数较小); a. 工作在老年区,回收算法:标记整理;工作在新生代,回收算法:复制; b. 单线程的垃圾回收器,只有一个垃圾回收线程在运行; c. 垃圾回收线程结束后,其他线程恢复运行; d. 触发垃圾回收时让所有线程在安全点停下【在垃圾回收过程中,对象的地址可能发生改变,为了保证安全使用对象地址,要

20、有哪几种垃圾回收器,各自的优缺点是什么?  


垃圾回收器主要分为以下几种:Serial,ParallelCMSG1

  1. Serial
  • 单线程垃圾回收器,该线程运行时,其他线程都暂停,使用复制算法;
  • 使用场景: 堆内存较小,适合个人电脑(CPU核数较小);

  1. 工作在老年区,回收算法:标记整理;工作在新生代,回收算法:复制;
  2. 单线程的垃圾回收器,只有一个垃圾回收线程在运行;
  3. 垃圾回收线程结束后,其他线程恢复运行;
  4. 触发垃圾回收时让所有线程在安全点停下【在垃圾回收过程中,对象的地址可能发生改变,为了保证安全使用对象地址,要求所有用户进程到达安全点后停下】


  1. Parallel (吞吐量优先)
  • 多线程垃圾回收器,堆内存较大,需要多核CPU的支持,工作在服务器上。
  • 目标:  让单位时间内,STW的时间最短
    例如:1小时内发生2次垃圾回收,每次垃圾回收0.2s,所以1小时内一共花费了0.4s,垃圾回收时间在程序运行时间中的占比,占比越小,说明吞吐量越大
  • 新生代垃圾回收器使用复制算法,老年代垃圾回收器使用标记整理算法。

  1. 工作在老年区,回收算法:标记整理;工作在新生代,回收算法:复制;
  2. 垃圾回收器会开启多个线程进行垃圾回收,垃圾回收时开启线程的个数默认与CPU核数相关;
  3. 垃圾回收线程结束后,其他线程恢复运行;
  4. CPU的使用程度:例如四核CPU,在触发吞吐量优先的垃圾回收器时,会同时开启4个线程进行垃圾回收,所以在很短时间内,CPU占用率达到100%。


  1. CMS (响应时间优先)
  • 多线程垃圾回收器,堆内存较大,需要多核CPU的支持,工作在服务器上。
  • 目标:  垃圾回收时,让单次STW的时间尽可能短
  • 例如:1小时内发生5次垃圾回收,每次STW时间都是0.1s所以一小时内一共花费了0.5s
  • 运作过程
  1. 初始标记:初始标记时,需要STW时间很快,只会列出根对象;
  2. 并发标记:继续标记剩余的垃圾并且不用STW;
  3. 重新标记:重新标记那些由于并发标记中用户程序产生的新的垃圾,需要STW;
  4. 并发清理:清除标记垃圾。

  • 在并发清理时,其他工作线程可能会产生新的垃圾->浮动垃圾,这些垃圾不能在本次垃圾回收时清理,需要等下一次垃圾回收时才会清理,所以要预留一些区间保存浮动垃圾;
  • 并发:垃圾回收线程和用户线程可以并发运行,抢占时间片,进一步减少了STW的时间【新生代:复制算法,老年代:标记清除,当CMS垃圾回收器并发失败后,会采取措施:让老年代的垃圾回收器退化到串行时的单线程垃圾回收,这会导致响应时间变得很长】
  • 由于CMS采用的是标记清除垃圾回收算法,可能会出现较多的内存碎片


  1. G1
  • 把堆划分成多个大小相等的Region,新生代和老年代不再物理隔离,多核 CPU 和大内存的场景下有很好的性能。新生代使用复制算法,老年代使用标记-整理算法。
  • 运作过程
  1. 初始标记:标记根对象(STW)
  2. 并发标记:跟踪标记根对象所有可达对象,找出要回收的对象【当老年代占用到整个堆空间的45%(默认)时,触发并发标记 】
  3. 最终标记:对并发标记阶段产生新的垃圾进行标记(STW)
  4. 筛选回收:对各个region区域进行回收价值与成本的排序,为了达到目标的回收时间,G1会挑选Region中最有价值的回收区域进行垃圾回收(最少时间回收最多的垃圾)(STW)

特点

  • 空间整合: 整体来看是基于“标记–整理”算法实现的收集器,从局部(两个Region之间)上来看是基于“复制”算法实现的,这意味着运行期间不会产生内存空间碎片。
  • 可预测的停顿:  能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在GC上的时间不得超过N毫秒。


21、什么是Stop The World ? 什么是安全点?


Stop The World

  • 进行垃圾回收的过程中,会涉及对象的移动。为了保证对象引用更新的正确性,必须暂停所有的用户线程,像这样的停顿,虚拟机设计者形象描述为Stop The World。也简称为STW。

安全点

  • 安全点是在程序执行期间的所有GC Root已知并且所有堆对象的内容一致的点。
  • 当线程运行到这类位置时,堆对象状态是确定一致的,JVM可以安全地进行操作,如GC,偏向锁解除等。

22、为什么需要STW?


在 java 应用程序中引用关系是不断发生变化的,那么就会有会有很多种情况来导致垃圾标识出错。

举个例子:

Object a  目前是个垃圾,GC 把它标记为垃圾,但是在清除前又有其他对象指向了 Object a,那么此刻 Object a 又不是垃圾了,那么如果没有 STW 就要去无限维护这种关系来去采集正确的信息。

23、详细说一下CMS的回收过程?


CMS(并发标记清除) 收集器是以获取最短回收停顿时间为目标的收集器,它在垃圾收集时使得用户线程和 GC 线程并发执行,因此在垃圾收集过程中用户也不会感到明显的卡顿。


CMS 回收过程分为以下四步:

  1. 始标记:初始标记时,需要STW时间很快,只会列出根对象;
  2. 并发标记:续标记剩余的垃圾并且不用STW ;
  3. 重新标记:重新标记那些由于并发标记中用户程序产生的新的垃圾,需要STW ;
  4. 并发清除:清除标记垃圾,由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发进行的。

24、CMS的问题是什么?

CMS 的问题:

  1. 并发回收导致CPU资源紧张:
  • 在并发阶段,它虽然不会导致用户线程停顿,但却会因为占用了一部分线程而导致应用程序变慢,降低程序总吞吐量。CMS默认启动的回收线程数是:(CPU核数 + 3)/ 4,当CPU核数不足四个时,CMS对用户程序的影响就可能变得很大。
  1. 无法清理浮动垃圾
  • 在并发清理时,其他工作线程可能会产生新的垃圾:浮动垃圾,这些垃圾不能在本次垃圾回收时清理,需要等下一次垃圾回收时才会清理,所以要预留一些区间保存浮动垃圾。
  1. 并发失败
  • 由于在垃圾回收阶段用户线程还在并发运行,那就还需要预留足够的内存空间提供给用户线程使用,因此CMS不能像其他回收器那样等到老年代几乎完全被填满了再进行回收,必须预留一部分空间供并发回收时的程序运行使用。默认情况下,当老年代使用了 92% 的空间后就会触发 CMS 垃圾回收,这个值可以通过 -XX: CMSInitiatingOccupancyFraction  参数来设置。
  • 这里会有一个风险:要是CMS运行期间预留的内存无法满足程序分配新对象的需要,就会出现一次“并发失败(Concurrent Mode Failure),这时候虚拟机将不得不启动后备预案:Stop The World,临时启用 Serial Old  来重新进行老年代的垃圾回收,这样一来停顿时间就很长了
  1. 内存碎片比较多
  • CMS 是使用了标记清除的算法去清理垃圾的,而这种算法的缺点就是会产生碎片化,后续可能会导致大对象无法分配从而触发和 Serial Old 一起配合使用来处理碎片化的问题,当然这也处于 STW的情况下,所以当 java 应用非常庞大时,如果采用了 CMS 垃圾回收器,产生了碎片化,那么在 STW 来处理碎片化的时间会非常之久。

25、详细说一下G1的回收过程?


G1把堆划分成多个大小相等的Region,新生代和老年代不再物理隔离,多核 CPU 和大内存的场景下有很好的性能。G1 在JDK9 之后成为服务端模式下的默认垃圾回收器。


G1 回收过程分为以下四步:

  1. 初始标记:标记根对象(STW)
  2. 并发标记:跟踪标记根对象所有可达对象,找出要回收的对象【当老年代占用到整个堆空间的45%(默认)时,触发并发标记 】
  3. 最终标记:对并发标记阶段产生新的垃圾进行标记(STW)
  4. 筛选回收:对各个region区域进行回收价值与成本的排序,为了达到目标的回收时间G1会挑选Region中最有价值的回收区域进行垃圾回收(最少时间回收最多的垃圾(STW)

特点

  • 空间整合: 整体来看是基于“标记–整理”算法实现的收集器,从局部(两个Region之间)上来看是基于“复制”算法实现的,这意味着运行期间不会产生内存空间碎片。
  • 可预测的停顿:  能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在GC上的时间不得超过N毫秒。

回收时机:G1在实现垃圾回收时一共提供了3种回收的方法,分别是新生代收集(Young GC),混合收集(Mixed GC),整堆收集(Full GC),这3种垃圾回收触发的时机通常如下:

  1. 应用程序分配对象时,发现内存不足,触发Young GC
  2. Young GC执行中,判断整体内存使用是否大于一定的阈值,如果大于启动并发标记;在并发标记完成后,当下一次启动垃圾回收称为Mixed GC,在Mixed GC执行过程中不仅回收新生代分区,同时也回收部分老生代分区;
  3. 在用程序分配对象时,发现内存不足,触发Young GC或者Mixed GC;垃圾回收结束后再次尝试分配对象,如果内存还不足,此时将触发Full GC

26、什么是三色标记算法?


三色标记算法,也就是垃圾回收器标记垃圾的时候使用的算法,简单来说,就是将对象分为三种颜色

  • 白色:表示对象尚未被垃圾收集器访问过。显然在可达性分析刚刚开始的阶段,所有的对象都是白色的,若在分析结束的阶段,仍然是白色的对象,即代表不可达。
  • 黑色:表示对象已经被垃圾收集器访问过,且这个对象的所有引用都已经扫描过。黑色的对象代表已经扫描过,它是安全存活的,如果有其他对象引用指向了黑色对象,无须重新扫描一遍。黑色对象不可能直接(不经过灰色对象)指向某个白色对象。
  • 灰色:表示对象已经被垃圾收集器访问过,但这个对象上至少存在一个引用还没有被扫描过。

标记过程:

  1. 在 GC 并发开始的时候,所有的对象均为白色;
  2. 在将所有的 GC Roots 直接应用的对象标记为灰色集合;
  3. 如果判断灰色集合中的对象不存在子引用,则将其放入黑色集合,若存在子引用对象,则将其所有的子引用对象存放到灰色集合,当前对象放入黑色集合;
  4. 按照此步骤 3 ,依此类推,直至灰色集合中所有的对象变黑后,本轮标记完成,并且在白色集合内的对象称为不可达对象,即垃圾对象;
  5. 标记结束后,为白色的对象为 GC Roots 不可达,可以进行垃圾回收。

三色标记算法的缺点

  1. 浮动垃圾:并发标记的过程中,若一个已经被标记成黑色或者灰色的对象,突然变成了垃圾,由于不会再对黑色标记过的对象重新扫描,所以不会被发现,那么这个对象不是白色的但是不会被清除,重新标记也不能从GC Root中去找到,所以成为了浮动垃圾,浮动垃圾对系统的影响不大,留给下一次GC进行处理即可
  2. 我们知道在并发标记的时候可能会出现误标的情况,这里举两个例子:
  • 刚开始标记为垃圾的对象,但是在并发标记过程中变为了存活对象
  • 刚开始标记为存活的对象,但是在并发标记过程中变为了垃圾对象

第一种情况影响还不算很大,只是相当于垃圾没有清理干净,待下一次清理的时候再清理一下就好了。第二种情况就危险了,正在使用的对象的突然被清理掉了,后果会很严重。那么产生上述第二种情况的原因是什么呢?

  • 新增了一条或多条黑色到白色对象的新引用
  • 删除了灰色对象到该白色对象的直接引用或间接引用。

当这两种情况都满足的时候就会出现这种问题了。所以为了解决这个问题,引入了增量更新 (Incremental Update)和 原始快照 (SATB)的方案:

  • 增量更新破坏了第一个条件增加新引用时记录 该引用信息,在后续 STW 扫描中重新扫描(CMS的使用方案)。
  • 原始快照破坏了第二个条件:删除引用时记录下来,在后续 STW 扫描时将这些记录过的灰色对象为根再扫描一次(G1的使用方案)。

27、有了CMS,为什么还要引入G1?


CMS最主要的优点在并发清除,低停顿,CMS同样有三个明显的缺点:

  1. 内存碎片比较多
  2. 并发回收导致CPU资源紧张
  3. 无法清理浮动垃圾

G1整体来看是基于“标记–整理”算法实现的收集器,从局部(两个Region之间)上来看是基于“复制”算法实现的,这意味着运行期间不会产生内存空间碎片


28、CMS和G1的区别?


  1. 使用的范围不一样:
  • CMS收集器是老年代的收集器,可以配合新生代的Serial和ParNew收集器一起使用。
  • G1收集器收集范围是老年代和新生代,不需要结合其他收集器使用 。
  1. STW的时间
  • CMS收集器以最短的停顿时间为目标的收集器。
  • G1收集器可预测垃圾回收的停顿时间(建立可预测的停顿时间模型)。
  1. 内存碎片
  • CMS收集器是使用“标记-清除”算法进行的垃圾回收,容易产生内存碎片。
  • G1收集器使用的是“标记-整理”算法,进行了空间整合,基本不会内存空间碎片。
  1. 回收过程不一样
  • CMS是初始标记、并发标记、重新标记、并发清理
  • G1是初始标记、并发标记、最终标记、筛选回收。

29、JDK1.8默认垃圾收集器是什么?一般推荐用哪个垃圾回收器?


查看默认垃圾回收器:

java -XX:+PrintCommandLineFlags -version

JDK默认是Parallel (吞吐量优先)垃圾回收器,在并发并不是非常高的情况下,可以尽可能的利用处理器资源。

如果想要提高服务的响应速度,可以采用CMS来降低停顿时间,或者采用了设计比较优秀的G1垃圾收集器,因为它不仅满足我们低停顿的要求,而且解决了CMS的浮动垃圾问题、内存碎片问题。

30、垃圾回收器应该怎么选择?


垃圾回收器的适用场景:

  1. Serial:   堆内存较小,适合个人电脑(CPU核数较小);
  2. Parallel:堆内存较大,需要多核CPU的支持,工作在服务器上,优先考虑应用程序的峰值性能;
  3. CMS/G1:如果响应时间比吞吐量优先级高,或者垃圾收集暂停必须保持在大约1秒以内。

31、JVM中一次完整的GC是什么样子的?  


  1. 对象优先在Eden分配
  • 新生代空间不足时,会触发Minor GC,Eden和From存活的对象使用Copy复制到to中,存活的对象年龄加1并且交换from和 to
  • Minor GC会引发Stop The World: 垃圾回收时会暂停其他用户线程,直到垃圾回收线程工作完了,才能恢复其他用户线程的运行,该暂停时间较短
  • 当对象寿命超过阈值时【最大为15次:因为存储对象寿命的长度为4bit,所以最大能存储15】,会晋升到老年代
  1. 当老年代空间不足时,会先尝试触发Minor GC,如果触发Minor GC之后,空间仍不足,会触发Full GC,Full GC 清理整个内存堆 – 包括新生代和老年代,STW时间更长, Full GC的垃圾回收算法是标记清除或是标记整理。
  2. 如果Full GC之后内存仍不足,就会报错

32、Minor GC/Young GC、Major GC/Old GC、Mixed GC、Full GC都是什么意思?


部分收集(Partial GC):指目标不是完整收集整个Java堆的垃圾收集,其中又分为:

  • 新生代收集(Minor GC/Young GC):指目标只是新生代的垃圾收集。
  • 老年代收集(Major GC/Old GC):指目标只是老年代的垃圾收集。目前只有CMS收集器会有单独收集老年代的行为。
  • 混合收集(Mixed GC):指目标是收集整个新生代以及部分老年代的垃圾收集。目前只有G1收集器会有这种行为。

整堆收集(Full GC):收集整个Java堆和方法区的垃圾收集。

33、Minor GC 和 Full GC 有什么不同呢?


  1. Minor GC只是新生代的垃圾收集。
  2. Full GC:  收集整个堆,包括新生代,老年代,方法区(在 JDK 1.8及以后,永久代被移除,换为metaspace 元空间实现)

34、Minor GC/Full GC 触发条件?


Minor GC触发条件当Eden区满时,触发Minor GC。

Full GC触发条件

  1. Minor GC之前检查老年代:在要进行 Minor GC 的时候,发现老年代可用的连续内存空间 < 新生代历次Minor GC后升入老年代的对象总和的平均大小,说明本次Minor GC后可能升入老年代的对象大小,可能超过了老年代当前可用内存空间,那就会触发 Full GC。
  2. Minor GC之后老年代空间不足:执行Minor GC之后有一批对象需要放入老年代,此时老年代就是没有足够的内存空间存放这些对象了,此时必须立即触发一次Full GC
  3. 老年代空间不足,老年代内存使用率过高,达到一定比例,也会触发Full GC。
  4. 空间分配担保失败( Promotion Failure),新生代的 To 区放不下从 Eden 和 From 拷贝过来对象,或者新生代对象 GC 年龄到达阈值需要晋升这两种情况,老年代如果放不下的话都会触发 Full GC。
  5. 方法区内存空间不足:如果方法区由永久代实现,永久代空间不足 Full GC。
  6. System.gc()等命令触发:System.gc()、jmap -dump 等命令会触发 full gc。

35、对象什么时候会进入老年代?


  1. 长期存活的对象将进入老年代
  • 每次Minor GC之后存活的对象年龄加1,当对象寿命超过阈值时【最大为15次:因为存储对象寿命的长度为4bit,所以最大能存储15】,会晋升到老年代。
  1. 大对象直接进入老年代
  • 有一些占用大量连续内存空间的对象在被加载就会直接进入老年代。这样的大对象一般是一些数组,长字符串之类的对象。
  1. 空间分配担保
  • 假如在Young GC之后,新生代仍然有大量对象存活,就需要老年代进行分配担保,把Survivor无法容纳的对象直接送入老年代。
  1. 动态对象年龄判定
  • 为了能更好地适应不同程序的内存状况,虚拟机并不是永远要求对象的年龄必须达到阈值15才能晋升老年代,如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代。

36、对象一定分配在堆中吗?有没有了解逃逸分析技术?


对象一定分配在堆中吗?

不一定的

  • 随着JIT编译期的发展与逃逸分析技术逐渐成熟,所有的对象都分配到堆上也渐渐变得不那么“绝对”了。其实,在编译期间,JIT会对代码做很多优化。其中有一部分优化的目的就是减少内存堆分配压力,其中一种重要的技术叫做逃逸分析

什么是逃逸分析?

  1. 通俗点讲,当一个对象被new出来之后,它可能被外部所调用,如果是作为参数传递到外部了,就称之为方法逃逸
  2. 除此之外,如果对象还有可能被外部线程访问到,例如赋值给可以在其它线程中访问的实例变量,这种就被称为线程逃逸

逃逸分析的好处

  1. 栈上分配
  • 如果确定一个对象不会逃逸到线程之外,那么就可以考虑将这个对象在栈上分配,对象占用的内存随着栈帧出栈而销毁,这样一来,垃圾收集的压力就降低很多。
  1. 同步消除
  • 线程同步本身是一个相对耗时的过程,如果逃逸分析能够确定一个变量不会逃逸出线程,无法被其他线程访问,那么这个变量的读写肯定就不会有竞争, 对这个变量实施的同步措施( 锁机制 )也就可以安全地消除掉
  1. 变量替换
  • 假如逃逸分析能够证明一个对象不会被方法外部访问,并且这个对象可以被拆散,那么可以不创建对象,直接创建若干个成员变量代替,可以让对象的成员变量在栈上分配和读写。

37、JVM新生代中为什么要分为Eden和Survivor

  1. 如果没有Survivor,Eden区每进行一次Minor GC,存活的对象就会被送到老年代。老年代很快被填满,触发Major GC,老年代的内存空间远大于新生代,进行一次Full GC消耗的时间比 Minor GC长得多,所以需要分为Eden和Survivor。
  2. Survivor的存在意义,就是减少被送到老年代的对象进而减少Full GC的发生,Survivor的预筛选保证,只有经历16次Minor GC还能在新生代中存活的对象,才会被送到老年代。
  3. 设置两个Survivor区最大的好处就是解决了碎片化刚刚新建的对象在Eden中,经历一次Minor GC,Eden中的存活对象就会被移动到第一块survivor space S0,Eden被清空;等Eden区再满了,就再触发一次Minor GC,Eden和S0中的存活对象又会被复制送入第二块survivor space S1(这个过程非常重要,因为这种复制算法保证了S1中来自S0和Eden两部分 的存活对象占用连续的内存空间,避免了碎片化的发生)
相关文章
|
16小时前
|
存储 安全 Java
从0开始回顾JVM---系列四
虚拟机执行 1、类的生命周期吗? 一个类从被加载到虚拟机内存中开始,到从内存中卸载,整个生命周期需要经过七个阶段:加载 、验证、准备、解析、初始化 、使用 和 卸载,其中验证、准备、解析三个部分统称为连接。 2、什么是类加载?类加载的过程? 类加载: 虚拟机把描述类的数据加载到内存里面,并对数据进行校验、解析和初始化,最终变成可以被虚拟机直接使用的class对象。 类加载过程如下: ● 加载:1、根据类的全限定类名获取二进制字节流;2、将字节流代表的静态存储结构转为方法区运行时存储数据结构;3、在堆中生成Class对象,作为方法区这个类数据访问入口; ● 验证: 检验加载的class文
|
16小时前
|
运维 监控 数据可视化
从0开始回顾JVM---系列五
JVM调优 1、有哪些常用的命令行性能监控和故障处理工具? 操作系统工具 ● top:显示系统整体资源使用情况 ● vmstat:监控内存和CPU ● iostat:监控IO使用 ● netstat:监控网络使用 JDK性能监控工具 ● jps:虚拟机进程查看 ● jstat:虚拟机运行时信息查看 ● jinfo:虚拟机配置查看 ● jmap:内存映像(导出) ● jhat:堆转储快照分析 ● jstack:Java堆栈跟踪 ● jcmd:实现上面除了jstat外所有命令的功能 2、了解哪些可视化的性能监控和故障处理工具? 以下是一些JDK自带的可视化性能监控和故障处理工具: ● JCons
|
17小时前
|
Java
jvm---类加载器(1)
jvm---类加载器(1)
|
16小时前
|
存储 Java 编译器
从0开始回顾JVM---系列一
引言 1、什么是JVM? JVM——Java虚拟机,它是Java实现平台无关性的基石。 Java程序运行的时候,编译器将Java文件编译成平台无关的Java字节码文件(.class),接下来对应平台JVM对字节码文件进行解释,翻译成对应平台匹配的机器指令并运行。 同时JVM也是一个跨语言的平台,和语言无关,只和class的文件格式关联,任何语言,只要能翻译成符合规范的字节码文件,都能被JVM运行。 内存管理 1、什么是JVM内存结构? Java1.8 之后的内存结果图: JVM将虚拟机分为5大区域,程序计数器、虚拟机栈、本地方法栈、java堆、方法区,其中方法区和堆是线程共享区,虚拟
|
16小时前
|
存储 缓存 算法
从0开始回顾JVM---系列二
11、什么情况下会发生内存泄露? 1. 静态集合类引起内存泄漏 ● 静态集合的生命周期和 JVM 一致,所以静态集合引用的对象不能被释放。 2. 单例模式 ● 单例对象在初始化后会以静态变量的方式在 JVM 的整个生命周期中存在。如果单例对象持有外部的引用,那么这个外部对象将不能被 GC 回收,导致内存泄漏。 3. 数据连接、IO、Socket等连接 ● 创建的连接不再使用时,需要调用 close 方法关闭连接,只有连接被关闭后,GC 才会回收对应的对象(Connection,Statement,ResultSet,Session)。忘记关闭这些资源会导致持续占有内存,无法被 GC 回收。 4
|
16小时前
|
安全 Java
《深入理解java虚拟机》学习笔记-----郑雨迪
《深入理解java虚拟机》学习笔记-----郑雨迪
45 0
|
10月前
|
算法 Java API
Java虚拟机System.gc()解析
对于Java语言来说是不用刻意手动去释放内存,同时,也尽可能不需要手动去干预Java虚拟机的GC行为。在本篇文章中,我们试图从多个方面去解析有关System.gc()API调用的最常见问题。希望对需要了解这块技术的朋友有所帮助。
142 0
|
存储 缓存 监控
JVM详解 --- 垃圾回收机制
JVM详解 --- 垃圾回收机制
JVM详解 --- 垃圾回收机制
|
算法 Java 数据格式
JVM:Java运行时数据区域----程序计数器
JVM:Java运行时数据区域----程序计数器
77 0
JVM:Java运行时数据区域----程序计数器
|
存储 Java 索引
JVM:Java运行时数据区域----Java虚拟机栈
JVM:Java运行时数据区域----Java虚拟机栈
85 0
JVM:Java运行时数据区域----Java虚拟机栈