(面试问题)jdk1.8用的是什么gc,有什么改进

京东面试真题:JDK1.8使用的是什么垃圾回收器,一般进行一次GC的时长以及GC的频率 JVM的垃圾收集器 阅读详情

前言


        与C语言不同,Java内存(堆内存)的分配与回收由JVM垃圾收集器自动完成,这个特性深受大家欢迎,能够帮助程序员更好的编写代码,本文以HotSpot虚拟机为例,说一说Java GC的那些事。


Java堆内存


        我们知道Java堆是被所有线程共享的一块内存区域,所有对象实例和数组都在堆上进行内存分配。为了进行高效的垃圾回收,虚拟机把堆内存划分成新生代(Young Generation)、老年代(Old Generation)和永久代(Permanent Generation)3个区域。



新生代


        新生代由 Eden 与 Survivor Space(S0,S1)构成,大小通过-Xmn参数指定,Eden 与 Survivor Space 的内存大小比例默认为8:1,可以通过-XX:SurvivorRatio 参数指定,比如新生代为10M 时,Eden分配8M,S0和S1各分配1M。


        Eden:希腊语,意思为伊甸园,在圣经中,伊甸园含有乐园的意思,根据《旧约·创世纪》记载,上帝耶和华照自己的形像造了第一个男人亚当,再用亚当的一个肋骨创造了一个女人夏娃,并安置他们住在了伊甸园。


        大多数情况下,对象在Eden中分配,当Eden没有足够空间时,会触发一次Minor GC,虚拟机提供了-XX:+PrintGCDetails参数,告诉虚拟机在发生垃圾回收时打印内存回收日志。


Survivor:意思为幸存者,是新生代和老年代的缓冲区域。


        当新生代发生GC(Minor GC)时,会将存活的对象移动到S0内存区域,并清空Eden区域,当再次发生Minor GC时,将Eden和S0中存活的对象移动到S1内存区域。


        存活对象会反复在S0和S1之间移动,当对象从Eden移动到Survivor或者在Survivor之间移动时,对象的GC年龄自动累加,当GC年龄超过默认阈值15时,会将该对象移动到老年代,可以通过参数-XX:MaxTenuringThreshold 对GC年龄的阈值进行设置。


老年代


        老年代的空间大小即-Xmx 与-Xmn 两个参数之差,用于存放经过几次Minor GC之后依旧存活的对象。当老年代的空间不足时,会触发Major GC/Full GC,速度一般比Minor GC慢10倍以上。


永久代


        在JDK8之前的HotSpot实现中,类的元数据如方法数据、方法信息(字节码,栈和变量大小)、运行时常量池、已确定的符号引用和虚方法表等被保存在永久代中,32位默认永久代的大小为64M,64位默认为85M,可以通过参数-XX:MaxPermSize进行设置,一旦类的元数据超过了永久代大小,就会抛出OOM异常。


        虚拟机团队在JDK8的HotSpot中,把永久代从Java堆中移除了,并把类的元数据直接保存在本地内存区域(堆外内存),称之为元空间。


这样做有什么好处?


        有经验的同学会发现,对永久代的调优过程非常困难,永久代的大小很难确定,其中涉及到太多因素,如类的总数、常量池大小和方法数量等,而且永久代的数据可能会随着每一次Full GC而发生移动。


        而在JDK8中,类的元数据保存在本地内存中,元空间的最大可分配空间就是系统可用内存空间,可以避免永久代的内存溢出问题,不过需要监控内存的消耗情况,一旦发生内存泄漏,会占用大量的本地内存。


ps:JDK7之前的HotSpot,字符串常量池的字符串被存储在永久代中,因此可能导致一系列的性能问题和内存溢出错误。在JDK8中,字符串常量池中只保存字符串的引用。


如何判断对象是否存活


        GC动作发生之前,需要确定堆内存中哪些对象是存活的,一般有两种方法:引用计数法和可达性分析法。


1、引用计数法


        在对象上添加一个引用计数器,每当有一个对象引用它时,计数器加1,当使用完该对象时,计数器减1,计数器值为0的对象表示不可能再被使用。


引用计数法实现简单,判定高效,但不能解决对象之间相互引用的问题。



public class GCtest {

    private Object instance = null;

    private static final int _10M = 10 * 1 << 20;

    // 一个对象占10M,方便在GC日志中看出是否被回收

    private byte[] bigSize = new byte[_10M];

 

    public static void main(String[] args) {

        GCtest objA = new GCtest();

        GCtest objB = new GCtest();

 

        objA.instance = objB;

        objB.instance = objA;

 

        objA = null;

        objB = null;

 

        System.gc();

    }

}


通过添加-XX:+PrintGC参数,运行结果:

[GC (System.gc()) [PSYoungGen: 26982K->1194K(75776K)] 26982K->1202K(249344K), 0.0010103 secs]


从GC日志中可以看出objA和objB虽然相互引用,但是它们所占的内存还是被垃圾收集器回收了。


2、可达性分析法


        通过一系列称为 “GC Roots” 的对象作为起点,从这些节点开始向下搜索,搜索路径称为 “引用链”,以下对象可作为GC Roots:

        本地变量表中引用的对象

        方法区中静态变量引用的对象

        方法区中常量引用的对象

        Native方法引用的对象


当一个对象到 GC Roots 没有任何引用链时,意味着该对象可以被回收。



在可达性分析法中,判定一个对象objA是否可回收,至少要经历两次标记过程:


        1、如果对象objA到 GC Roots没有引用链,则进行第一次标记。

        2、如果对象objA重写了finalize()方法,且还未执行过,那么objA会被插入到F-Queue队列中,由一个虚拟机自动创建的、低优先级的Finalizer线程触发其finalize()方法。finalize()方法是对象逃脱死亡的最后机会,GC会对队列中的对象进行第二次标记,如果objA在finalize()方法中与引用链上的任何一个对象建立联系,那么在第二次标记时,objA会被移出“即将回收”集合。


看看具体实现


public class FinalizerTest {

    public static FinalizerTest object;

    public void isAlive() {

        System.out.println("I'm alive");

    }

 

    @Override

    protected void finalize() throws Throwable {

        super.finalize();

        System.out.println("method finalize is running");

        object = this;

    }

 

    public static void main(String[] args) throws Exception {

        object = new FinalizerTest();

 

        // 第一次执行,finalize方法会自救

        object = null;

        System.gc();

 

        Thread.sleep(500);

        if (object != null) {

            object.isAlive();

        } else {

            System.out.println("I'm dead");

        }

 

        // 第二次执行,finalize方法已经执行过

        object = null;

        System.gc();

 

        Thread.sleep(500);

        if (object != null) {

            object.isAlive();

        } else {

            System.out.println("I'm dead");

        }

    }

}



执行结果:


method finalize is runningI'm aliveI'm dead


从执行结果可以看出:


第一次发生GC时,finalize方法的确执行了,并且在被回收之前成功逃脱;

第二次发生GC时,由于finalize方法只会被JVM调用一次,object被回收。


当然了,在实际项目中应该尽量避免使用finalize方法。


收集算法


垃圾收集算法主要有:标记-清除、复制和标记-整理。


1、标记-清除算法


对待回收的对象进行标记。


算法缺点:效率问题,标记和清除过程效率都很低;空间问题,收集之后会产生大量的内存碎片,不利于大对象的分配。


2、复制算法


复制算法将可用内存划分成大小相等的两块A和B,每次只使用其中一块,当A的内存用完了,就把存活的对象复制到B,并清空A的内存,不仅提高了标记的效率,因为只需要标记存活的对象,同时也避免了内存碎片的问题,代价是可用内存缩小为原来的一半。


3、标记-整理算法


在老年代中,对象存活率较高,复制算法的效率很低。在标记-整理算法中,标记出所有存活的对象,并移动到一端,然后直接清理边界以外的内存。


对象标记过程


在可达性分析过程中,为了准确找出与GC Roots相关联的对象,必须要求整个执行引擎看起来像是被冻结在某个时间点上,即暂停所有运行中的线程,不可以出现对象的引用关系还在不断变化的情况。


如何快速枚举GC Roots?


GC Roots主要在全局性的引用(常量或类静态属性)与执行上下文(本地变量表中的引用)中,很多应用仅仅方法区就上百兆,如果进行遍历查找,效率会非常低下。


在HotSpot中,使用一组称为OopMap的数据结构进行实现。类加载完成时,HotSpot把对象内什么偏移量上是什么类型的数据计算出来存储到OopMap中,通过JIT编译出来的本地代码,也会记录下栈和寄存器中哪些位置是引用。GC发生时,通过扫描OopMap的数据就可以快速标识出存活的对象。


如何安全的GC?


线程运行时,只有在到达安全点(Safe Point)才能停顿下来进行GC。


基于OopMap数据结构,HotSpot可以快速完成GC Roots的遍历,不过HotSpot并不会为每条指令都生成对应的OopMap,只会在Safe Point处记录这些信息。


所以Safe Point的选择很重要,如果太少可能导致GC等待的时间太长,如果太频繁可能导致运行时的性能问题。大部分指令的执行时间都非常短暂,通常会选择一些执行时间较长的指令作为Safe Point,如方法调用、循环跳转和异常跳转等。


关于Safe Point更多的信息,可以看看这篇文章《 JVM的Stop The World,安全点,黑暗的地底世界 》(http://calvin1978.blogcn.com/articles/safepoint.html)。


发生GC时,如何让所有线程跑到最近的Safe Point再暂停?


当发生GC时,不直接对线程进行中断操作,而是简单的设置一个中断标志,每个线程运行到Safe Point的时候,主动去轮询这个中断标志,如果中断标志为真,则将自己进行中断挂起。


这里忽略了一个问题,当发生GC时,运行中的线程可以跑到Safe Point后进行挂起,而那些处于Sleep或Blocked状态的线程在此时无法响应JVM的中断请求,无法到Safe Point处进行挂起,针对这种情况,可以使用安全区域(Safe Region)进行解决。


Safe Region是指在一段代码片段中,对象的引用关系不会发生变化,在这个区域中的任何位置开始GC都是安全的。


1、当线程运行到Safe Region的代码时,首先标识已经进入了Safe Region,如果这段时间内发生GC,JVM会忽略标识为Safe Region状态的线程;


2、当线程即将离开Safe Region时,会检查JVM是否已经完成GC,如果完成了,则继续运行,否则线程必须等待直到收到可以安全离开Safe Region的信号为止;


垃圾收集器


Java虚拟机规范并没有规定垃圾收集器应该如何实现,用户可以根据系统特点对各个区域所使用的收集器进行组合使用。



上图展示了7种不同分代的收集器,如果两两之间存在连线,说明可以组合使用。


1、Serial收集器(串行GC)


Serial 是一个采用单个线程并基于复制算法工作在新生代的收集器,进行垃圾收集时,必须暂停其他所有的工作线程。对于单CPU环境来说,Serial由于没有线程交互的开销,可以很高效的进行垃圾收集动作,是Client模式下新生代默认的收集器。


2、ParNew收集器(并行GC)


ParNew其实是serial的多线程版本,除了使用多条线程进行垃圾收集之外,其余行为与Serial一样。


3、Parallel Scavenge收集器(并行回收GC)


Parallel Scavenge是一个采用多线程基于复制算法并工作在新生代的收集器,其关注点在于达到一个可控的吞吐量,经常被称为“吞吐量优先”的收集器。


吞吐量 = 用户代码运行时间 /(用户代码运行时间 + 垃圾收集时间)


Parallel Scavenge提供了两个参数用于精确控制吞吐量:


-XX:MaxGCPauseMillis 设置垃圾收集的最大停顿时间

-XX:GCTimeRatio 设置吞吐量大小


4、Serial Old收集器(串行GC)


Serial Old 是一个采用单线程基于标记-整理算法并工作在老年代的收集器,是Client模式下老年代默认的收集器。


5、Parallel Old收集器(并行GC)


Parallel Old是一个采用多线程基于标记-整理算法并工作在老年代的收集器。在注重吞吐量以及CPU资源敏感的场合,可以优先考虑Parallel Scavenge和Parallel Old的收集器组合。


6、CMS收集器(并发GC)


CMS(Concurrent Mark Sweep)是一种以获取最短回收停顿时间为目标的收集器,工作在老年代,基于“标记-清除”算法实现,整个过程分为以下4步:


  1. 初始标记:这个过程只是标记以下GC Roots能够直接关联的对象,但是仍然会Stop The World;

  2. 并发标记:进行GC Roots Tracing的过程,可以和用户线程一起工作。

  3. 重新标记:用于修正并发标记期间由于用户程序继续运行而导致标记产生变动的那部分记录,这个过程会暂停所有线程,但其停顿时间远比并发标记的时间短;

  4. 并发清理:可以和用户线程一起工作。


CMS收集器的缺点:


  1. 对CPU资源比较敏感,在并发阶段,虽然不会导致用户线程停顿,但是会占用一部分线程资源,降低系统的总吞吐量。

  2. 无法处理浮动垃圾,在并发清理阶段,用户线程的运行依然会产生新的垃圾对象,这部分垃圾只能在下一次GC时收集。

  3. CMS是基于标记-清除算法实现的,意味着收集结束后会造成大量的内存碎片,可能导致出现老年代剩余空间很大,却无法找到足够大的连续空间分配当前对象,不得不提前触发一次Full GC。


JDK1.5实现中,当老年代空间使用率达到68%时,就会触发CMS收集器,如果应用中老年代增长不是太快,可以通过-XX:CMSInitiatingOccupancyFraction参数提高触发百分比,从而降低内存回收次数提高系统性能。


JDK1.6实现中,触发CMS收集器的阈值已经提升到92%,要是CMS运行期间预留的内存无法满足用户线程需要,会出现一次”Concurrent Mode Failure”失败,这是虚拟机会启动Serial Old收集器对老年代进行垃圾收集,当然,这样应用的停顿时间就更长了,所以这个阈值也不能设置的太高,如果导致了”Concurrent Mode Failure”失败,反而会降低性能,至于如何设置这个阈值,还得长时间的对老年代空间的使用情况进行监控。


7、G1收集器


G1(Garbage First)是JDK1.7提供的一个工作在新生代和老年代的收集器,基于“标记-整理”算法实现,在收集结束后可以避免内存碎片问题。


G1优点:


  1. 并行与并发:充分利用多CPU来缩短Stop The World的停顿时间;

  2. 分代收集:不需要其他收集配合就可以管理整个Java堆,采用不同的方式处理新建的对象、已经存活一段时间和经历过多次GC的对象获取更好的收集效果;

  3. 空间整合:与CMS的”标记-清除”算法不同,G1在运行期间不会产生内存空间碎片,有利于应用的长时间运行,且分配大对象时,不会导致由于无法申请到足够大的连续内存而提前触发一次Full GC;

  4. 停顿预测:G1中可以建立可预测的停顿时间模型,能让使用者明确指定在M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。


使用G1收集器时,Java堆的内存布局与其他收集器有很大区别,整个Java堆会被划分为多个大小相等的独立区域Region,新生代和老年代不再是物理隔离了,都是一部分Region(不需要连续)的集合。G1会跟踪各个Region的垃圾收集情况(回收空间大小和回收消耗的时间),维护一个优先列表,根据允许的收集时间,优先回收价值最大的Region,避免在整个Java堆上进行全区域的垃圾回收,确保了G1收集器可以在有限的时间内尽可能收集更多的垃圾。


不过问题来了:使用G1收集器,一个对象分配在某个Region中,可以和Java堆上任意的对象有引用关系,那么如何判定一个对象是否存活,是否需要扫描整个Java堆?其实这个问题在之前收集器中也存在,如果回收新生代的对象时,不得不同时扫描老年代的话,会大大降低Minor GC的效率。


针对这种情况,虚拟机提供了一个解决方案:G1收集器中Region之间的对象引用关系和其他收集器中新生代与老年代之间的对象引用关系被保存在Remenbered Set数据结构中,用来避免全堆扫描。G1中每个Region都有一个对应的Remenbered Set,当虚拟机发现程序对Reference类型的数据进行写操作时,会产生一个Write Barrier暂时中断写操作,检查Reference引用的对象是否处于相同的Region中,如果不是,则通过CardTable把相关引用信息记录到被引用对象所属Region的Remenbered Set中。


JDK10 GC新特性,到底能带来多大提升? 本文介绍了JDK9和JDK10在垃圾收集(GC)方面的改进,包括统一日志格式(JEP 214)、G1并发Full GC(JEP 304)和Parallel GC的TLAB优化(JEP 307)。JDK10进一步优化了G1的分代晋升效率,并引入了实验性ZGC。相较于JDK8,新版GC在日志管理、并发性能和监控能力上显著提升。文章还通过Visual VM的对象直方图功能,展示了如何分析对象年龄分布,结合GC日志参数优化内存管理。 阅读详情

相关推荐

从JDK8到JDK14:阿里巴巴面试题探索Java的演进之路!

各位小伙伴们,快来了解最新的Java开发利器!从JDK8到JDK14,每一次更新都将我们带入全新的Java世界。本文将全面解读JDK的新特性,助你掌握最前沿的技术,提升开发效率,走在行业前沿!

孤芳不自赏 904

Java GC笔记

Java堆是被所有线程共享的一块内存区域,所有对象实例和数组都在堆上进行内存分配。为了进行高效的垃圾回收,虚拟机把堆内存划分成新生代(Young Generation)、老年代(Old Generation)和永久代(Permanent Generation)3个区域。 新生代由 Eden 与 Survivor Space(S0,S1)构成,大小通过-Xmn参数指定,Eden 与 Survivor

Em_dark的博客 753

1、JDK JRE JVM 面试问了

阿萨上的

ss 的博客 780

【JDK】【04】JDK1.8 G1垃圾收集

1.官网 https://www.oracle.com/technetwork/cn/articles/java/g1gc-1984535-zhs.html#Unlock

huiyanshizhen21的博客 4355

伯德图详解:从传递函数到系统稳定性的频域分析

在自动控制与控制系统设计中,理解系统对不同频率输入信号的响应特性,是分析和设计稳定系统的核心基础。频率响应描述了系统对正弦输入的幅值增益与相位变化规律,而伯德图作为最直观的频域分析工具,通过对数坐标将宽频带特性压缩成一条清晰曲线,让工程师无需复杂计算即可快速评估系统性能。从典型环节的渐近线绘制,到相位裕度、幅值裕度的读取,伯德图贯穿了系统稳定性判断、控制器参数整定及噪声抑制等关键场景。本文结合实际调试经验,系统讲解伯德图的绘制原理与读图方法,帮助读者快速掌握从传递函数到工程应用的核心技能。

weixin_34535286的博客 344

MAX3232芯片引脚功能详解与外围电路设计避坑指南(从电荷泵到静电防护)

本文详细解析了MAX3232芯片的引脚功能与外围电路设计,重点介绍了其电荷泵架构和RS232通信接口的应用。通过实际案例和参数对比,提供了电路设计中的常见问题解决方案和静电防护建议,帮助工程师优化工业控制与嵌入式系统中的通信可靠性。

weixin_30596165的博客 436

如何查看JDK不同版本默认使用的垃圾回收器(JDK 1.8 默认采用的是ParallelGC)【图文】

查看JDK不同版本使用的垃圾回收器,设置参数:-XX:+PrintCommandLineFlags(我截图中少了一个加号+) 结论:JDK 1.8 默认采用的是ParallelGC ,JDK 1.9默认采用的就是 G1 垃圾回收器了。 两外:推荐 --> 看完面试就够了-- JVM垃圾回收篇(Garbage Collection)两万字【图文并茂】 我写的,哈哈哈,自我推荐了 有用点个关注,手留余香!???? ???? ???? ...

qq_43012792的博客 7999

腾讯ACE反作弊系统:内核驱动与AI行为分析如何守护游戏公平

在游戏安全领域,反作弊技术是保障公平竞技环境的核心防线。其基本原理是通过监控系统关键行为,识别并阻断非法的第三方程序干预。从技术实现看,现代反作弊方案普遍采用分层防御架构,结合用户态模块进行应用层检测,并依赖内核态驱动实现底层深度监控,以此构建纵深防御体系。这种技术的核心价值在于,它能有效对抗从简单内存修改到高级驱动级作弊等多种威胁,维护游戏经济系统和玩家体验的完整性。随着作弊手段的演进,行为分析与AI赋能变得至关重要,系统通过机器学习模型分析进程行为序列的异常模式,即使面对未知特征的外挂变种也能进行有效识

weixin_33978578的博客 747

JVM垃圾回收GC 详解(java1.8)

目录垃圾判断算法(你是不是垃圾?)引用计数法可达性算法对象的引用强引用软引用弱引用虚引用对象的自我救赎垃圾回收算法--分代标记清除算法复制算法标记整理法垃圾处理器最容易想到的一种方式是引用计数法,啥叫引用计数法,简单地说,就是对象被引用一次,在它的对象头上加一次引用次数,如果没有被引用(引用次数为 0),则此对象可回收 以上代码 ref 引用了右侧定义的对象,所以引用次数是 1 如果在上述代码后面添加一个 ref = null,则由于对象没被引用,引用次数置为 0,由于不被任何变量引用,此时即被回收,

qq_63815371的博客 1871

从零上手SKILL脚本:在Virtuoso中实现版图绘制自动化

本文详细介绍了如何使用SKILL脚本在Virtuoso中实现版图绘制自动化,从基础操作到高级技巧全面覆盖。通过抓取操作日志、转换交互式函数为程序式函数,以及核心函数深度解析,帮助读者快速掌握SKILL脚本编程,大幅提升版图设计效率。文章还提供了实际工程应用案例和调试优化技巧,适合从零开始的初学者。

weixin_28742653的博客 765

手把手教你在全新服务器内网安装OpenEuler 22.03 LTS SP4+ 安装 openGuass 5.0.0(LTS) 数据库

openEuler是面向数字基础设施的操作系统,支持服务器、云计算、边缘计算、嵌入式等应用场景,支持多样性计算,致力于提供安全、稳定、易用的开源服务器Linux操作系统。

cgqyw的专栏 3740

从 JDK 8 到 JDK 17,GC 性能大幅提升

点击“终码一生”,关注,置顶公众号 每日技术干货,第一时间送达 JDK17 发布已经几个月了,其中不仅包含很多新语言功能,而且与旧版 JDK 相比,性能提升也非常明显。与之前 LTS 版本的 JDK 8 和 JDK 11 相比,JDK17 的性能提升尤为明显。此次性能的提升大部分来自 JVM 的新功能和优化,在本文中我们就来重点谈一谈垃圾收集的改进。 最近,我发表过一个演讲,重点介绍了自 JDK 8 以来 G1 中的新特性,本文将在此基础之上进一步扩展,以涵盖 Parallel GC 和

终码一生 1万+

【DRAM存储器二十六】DDR4介绍-DDR4 SDRAM的主要技术特性之CA Parity、CRC Write date

详述DDR4的CA奇偶检验和写数据CRC校验功能

highman110的博客 1298

从 JDK 8 到 JDK 17,GC 性能大幅提升(2)

针对以上面试题,小编已经把面试题+答案整理好了。

2401_83916326的博客 1120

RGB渐变颜色转换公式及例程

设Step=51,将RGB(255,0,0)颜色渐变为RGB(0,255,0),即RGB(255,0,0)经过51次颜色渐变转为RGB(0,255,0);设Step=51,将RGB(0,255,0)颜色渐变为RGB(0,0,255),即RGB(0,255,0)经过51次颜色渐变转为RGB(0,0,255);设Step=51,将RGB(0,0,255)颜色渐变为RGB(255,0,0),即RGB(0,0,255)经过51次颜色渐变转为RGB(255,0,0);分步骤的方式,使其渐变色循环整个颜色值;

1万+

vue3 - 最新详细实现高德地图绘制动态热力图详细教程,在某区域或城市地图上做“热力图层“展示人流量、旅游人口密度、热量图、全国地区地理热力图,利用颜色的深浅表示密度或强度等场景(详细示例代码教程)

vue3,nuxt3,高德地图,热力图,绘制热力图层,人流量,vue3使用高德地图实现某个区域热力图,vue3高德地图api加载热力图及关闭,接收热力图数据并渲染热力图,关掉热力图,Vue使用高德API制作热力图,热力图加载不出来,电子围栏围住热力图,vue3中使用高德地图渲染热力图组件,高德地图使用热力图详细教程,报错,卡顿,出不来怎么办,无法关闭,怎么解决这个问题,出错,城市名称,城市某个街道,城区,省份,市区,县城,乡镇,村,各省份的热力图,交通流量,人口流量,密度,旅游出行,人口数量,颜色介绍,深浅

✅ 精选推荐文章 5207

从 JDK 8 到 JDK 17,GC 性能大幅提升(1)

Java面试核心知识点一共有30个专题,足够读者朋友们应付面试啦,也节省朋友们去到处搜刮资料自己整理的时间!Java面试核心知识点《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!试核心知识点《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

2401_83916283的博客 1098

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

JDK从8升级到11,使用 G1 GC,HBase性能下降20%。JDK 到底干了什么

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!结论:使用 G1 GC,JDK 11 相对于 JDK 8 来说性能明显下降。3原因分析=====从 JDK 8 到 JDK 11, G1 GC 做了非常多的优化用于提高性能。为什么 JDK 11 对于应用者来说更不友好?简单的总结一下从 JDK 8 到 JDK 11 做得一些比较大的设计变化,如下表所示:由于从 JDK 8 到 JDK 11 特性变化太多,对于这样的性能下降问题,为了能快速有效的解决,我们做了

sgegv的博客 929

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

JAVA面试题分享三百七十八:JDK 21:GC变得越来越好了

当比较 JDK 版本之间的性能时,很难准确地说出哪些功能带来了某种性能提升。但是很容易看出自 JDK 8 以来,Java 平台整体的性能显著提高。在本文中,我将使用 SPECjbb®2015 来展示性能增益。这是一个众所周知的标准基准测试,非常适合展示 GC 的变化。max-jOPS- 原始吞吐量- 在延迟约束下的吞吐量GC 的改进将提高这两个得分,但限制延迟得分的改进更与 GC 的变化相关。基本上,较短的暂停将给出更好的得分。对于原始吞吐量得分,JIT 和 Java 平台的其他部分的改进也起到作用。

之乎者也·的博客 1489

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

JDK 21:GC 不断改进,性能更上一层楼

???? 这是一个或许对你有用的社群???? 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料:《项目实战(视频)》:从书中学,往事上“练”《互联网高频面试题》:面朝简历学习,春暖花开《架构 x 系统设计》:摧枯拉朽,掌控面试高频场景题《精进 Java 学习指南》:系统学习,互联网主流技术栈《必读 Java 源码专栏》:知其然,知其所以然????这是一个或许...

芋艿V 658

Java面试-如何通过 JVM 参数优化 GC 性能?

文章摘要(142字): 《JVM垃圾回收调优全攻略》系统解析了GC性能优化的核心方法论。从JVM内存结构、GC类型对比,到关键参数详解(堆大小、年轻代比例、回收器选择),提供高吞吐批处理、低延迟Web、超大堆等场景的实战调优方案。重点剖析G1回收器的Region设计、可预测停顿机制,并对比ZGC/Shenandoah等前沿技术。附有监控技巧、面试题解析及避坑指南,帮助开发者从“GC频繁”过渡到“丝般顺滑”的高性能状态。(附JVM参数速查表)

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

Java 面试场景题:8 大高频问题(Full GC / 秒杀 / 幂等性),方案 + 代码直接用

本文就针对 常问的 Java 面试高频场景题,拆解 “问题分析→技术选型→实现方案→注意事项” 的完整答题框架,帮你形成 “有逻辑、有细节、有深度” 的回答,让面试官觉得 “你真的做过这些事”。

2501_93207597的博客 1808
上一篇: 面试问题(你喜欢和什么样的人一起工作,不喜欢和什么样的人一起工作)
下一篇: 面试问题(什么是happen-before)
hxpjava1
博客等级 码龄19年 1365粉丝 511原创
评论 10
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值