`
enetor
  • 浏览: 188146 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java性能优化(JVM)

阅读更多

转自:http://www.ibm.com/developerworks/cn/java/j-lo-jvm-perf/

 

开始之前

Java 平台已无处不在,Java EE、Java SE、Java ME 和 Java Card,Java 的发展为无数程序员提供了工作机会,都是“Java”,然而除了基本的 Java 语法大都一致外,程序员必须基于不同的平台有不同的考虑,学习不同平台的特点:

  1. 不同平台的环境

    Java EE 所运行的硬件服务器、操作系统,Java SE 所在 PC 机的体系结构(X86/X64、MAC、SPARC 等),Java ME 所运行的手机或移动设备,Java Card 所在的智能卡芯片类型等;

  2. 不同平台虚拟机的特点

    如是否支持多线程(这似乎是毋庸置疑,但是在 Java Card 平台上,由于计算资源相当有限,多线程目前还不被支持),Java EE 和 Java SE 的虚拟机特性几乎相同,而 Java ME 虚拟机(KVM)根据移动设备的特点进行裁剪和优化,以适应于有限的物理内存和存储空间,而根据设备处理能力的强弱还分为 CDC(Connected Device Configuration,联网设备配置)和 CLDC(Connected Limited Device Configuration,联网受限设备配置),更小设备和智能卡的虚拟机 JCVM(Java Card VM)更是裁剪了许多特性,如多线程、许多复杂数据类型的支持、主动的垃圾收集机制等,这甚至导致了对 Java 语法集的裁剪;

  3. 不同平台的 API 和可用的第三方库

    Java EE 和 Java SE 是超集与子集的关系,因为她们所处的计算机平台和操作系统目前很好的兼容,而 Java ME 和 Java Card 与 EE 和 SE 是 Totally different,除了 java.lang.*,部分 java.io.* 等核心类库保留外,其他的 API 和类库完全不同。java.microedition.* 和 javax.microedition.* 表明这是 ME 平台,javacard.* 表明这是 Java Card 平台。同时,由于 EE 和 SE 平台的普及程度和开发者人数,使得之上的第三方库十分海量。深入了解和掌握平台的 API 和库是不同平台程序员进阶的必由之路。

从这个角度上说,Java 在不同的平台之间,并不是“一次编写、处处运行”,考虑应用程序的设计和优化的时候,首先要看是在什么平台上,因为源于以上不同的特点,编程模型、设计模 式,甚至语言集都不尽相同。在这里我们着重考虑 Java EE 和 SE 的视角,但有很多设计、编程原则和习惯对于所有平台的程序员来说,都适用。

 

Java 虚拟机

Java 虚拟机是支持 Java 语言运行的基础,避开过多的 JVM 和实现的技术细节,我们对基础架构进行了解,是进行应用程序优化必不可少的。如下图所示:


图 1. Java 虚拟机体系结构
图 1. Java 虚拟机体系结构

  1. 类装载子系统 :通过类的全限定名(包名和类名,网络装载还包括 URL)将 Class 装载进运行时数据区;
  2. 方法区 :Class 对于所有方法和 static 静态数据的定义存储在这里,它就像一张表或数组,让程序执行时在这里找到相应方法的 Java 字节码和静态数据;
  3. Java 堆 :Java 对象的持久化存储区,从类实例化而来的对象存储在此,垃圾收集也在此进行,若是空间不够容纳当前所有对象,Out Of Memory 的异常将会抛出,对 Java 堆和垃圾收集的认识对应用性能调优很关键;
  4. Java 栈 :Java 方法的字节码执行的地方,方法中局部变量的生命周期都在栈中,栈的大小是我们要考虑的一个关键点,它直接决定了方法调用的层数,这对递归程序来说尤为重 要。我们所用的 JVM 都是基于 Java 栈的运行机制,而有一个例外的实现,Google 移动设备操作系统 Android 的虚拟机 Dalvik 则是基于寄存器的机制(Dalvik 虽然支持 Java 语言开发,但从虚拟机的角度看,并不符合 Java 标准),关于虚拟机实现时,栈和寄存器机制的比较,请参考论文“Virtual Machine Showdown: Stack Versus Registers ”;
  5. 程序计数器 :对于基于栈实现的 JVM,这几乎是唯一寄存器了,它用来指示当前 Java 执行引擎执行到哪条 Java 字节码,指针指向方法区的字节码;
  6. 本地方法栈 :这是 Java 调用操作系统本地库的地方,用来实现 JNI(Java Native Interface,Java 本地接口);
  7. 执行引擎 :JVM 的心脏,控制装入 Java 字节码并解析;
  8. 本地接口 :连接了本地方法栈和操作系统库。

Java 字节码是 JVM 的指令,所有 Java 平台虚拟机有各自的指令集,而大部分指令相同,共 200 条左右,Java Card 虚拟机由于支持的数据类型少,相应的指令较少。部分虚拟机实现商为了优化性能,增加了一些自己特有的指令,当对于 Java 程序员来说,是透明的。下面是一段 Java 方法的字节码示例:


清单 1. Java 字节码例

				
 /* 0x000092c4:0x04a7: */ _SCONST_0, 
 /* 0x000092c5:0x04a8: */ _SCONST_0, 
 /* 0x000092c6:0x04a9: */ _INVOKESTATIC, HIGH(0x08e8), LOW(0x08e8), 
 /* 0x000092c9:0x04ac: */ _POP, 
 /* 0x000092ca:0x04ad: */ _INVOKESTATIC, HIGH(0x8046), LOW(0x8046),

 /* 0x000092cd:0x04b0: */ _IFEQ, 84, 
 /* 0x000092cf:0x04b2: */ _INVOKESTATIC, HIGH(0x8044), LOW(0x8044), 
 /* 0x000092d2:0x04b5: */ _GOTO, 79, 
 /* 0x000092d4:0x04b7: */ _ASTORE, 7,   

 

当程序计数器中值为 0x000092ca:0x04ad ,表明下一条即将执行字节码为 _INVOKESTATIC, HIGH(0x8046), LOW(0x8046) ,该字节码表明将调用某个静态方法。

Java 语言一大好处就是不用关心对于内存的分配和回收,一切由垃圾收集器搞定。然而这并不代表 Java 程序员可以高枕无忧,再高效的收集器也可能因为滥用而导致性能问题。我们已经知道,Java 程序所涉及的空间分配和回收包括:

  1. Java 堆,创建的 Java 对象(包括数组,数组也是一种对象)分配在堆中,垃圾收集对象来释放空间;
  2. Java 栈,栈划分为操作数栈、栈帧数据和局部变量区,方法中分配的局部变量在栈中,同时每一次方法的调用都会在栈中分配栈帧,因此程序员在设计和开发应用时需考虑调用层数。

来看一段字节码在 Java 栈中的执行示例,100 与 98 相加:


清单 2. 整数加法运算的 Java 字节码

				
 iload_0   // 载入局部变量 0,整型,压入栈中
 iload_1   // 载入局部变量 1,整型,压入栈中
 iadd      // 弹出两个整型数,相加,将结果压入栈
 istore_2  // 弹出整型数,存入局部变量 2 



图 2. 整数加法运算 Java 栈行为
图 2. 整数加法运算 Java 栈行为

此外,对于 JVM,还需了解支持的数据类型和它们占用的空间:


图 3. Java 数据类型
图 3. Java 数据类型


按代垃圾收集机制

虽然各家 JVM 的实现(Sun Hotspot、IBM J9、Oracle JRockit 等)不同,但均采用了按代的垃圾收集机制。垃圾收集就是标识出虚拟机中不被用到的垃圾对象,删除以回收空间。按代垃圾收集算法主要分为三种:

  • 复制算法,空间被分为等大的两块,从根开始访问每一个关联的活跃对象,将空间 A 的活跃对象全部复制到空间 B,然后一次性回收整个空间 A,优点:只访问活跃对象,将所有活动对象复制走之后就清空整个空间,不用去访问死对象,所以遍历空间的成本较小,缺点:需要巨大的复制成本和较多的内 存;
  • 标记清除算法,从根开始访问所有活跃对象,标记为活跃对象。然后再遍历一次整个内存区域,把所有没有标记活跃的对象进行回收处理,优点:不需要额外的空间,缺点:较长的 GC 暂停时间,较大的扫描时间开销,产生较多的空间碎片;
  • 标记清除整理算法,综合上两种算法的优点,先标记活跃对象,然后将其合并成较大的内存块。

代的划分:

  • 年轻代:新创建的对象分配在此,研究表明,大部分程序所产生的对象都在此消亡,几乎所有的收集器为年轻代使用复制算法,年轻代又被划分为 1 个伊甸园区和 2 个存活区用来实施复制算法;
  • 年老代:从年轻代存活下来的对象被复制到年老代,主要实施标记清除或标记清除整理算法;
  • 持久代:装载的类数据和信息存储于此,无可消亡对象。

Java 虚拟机都提供了相应的选项来设置各个代所占用区的大小,无论是 Java EE 的服务器应用,还是 Java SE 桌面应用或产品,都需要经过对运行时对象创建和消亡状态的分析,进行这些选项的合理设置,才能获得较好的性能提升,毕竟垃圾收集是一项耗时的工作。读者可 以进一步深入研究相关的虚拟机选项,为自己的应用程序设置优化的数值。

垃圾收集按频率可分为:

  • 次收集(Minor Collection):频繁发生在年轻代,收集快速消亡的对象;
  • 主收集(Major Collection):年轻代和年老代的全范围收集,频率很低。

垃圾收集运行时,同一个 CPU 上的所有其它线程都将会被阻塞,所以对于 Java 应用程序来说,整个世界似乎停滞了,当整个标记、清除、整理周期完成后,所有应用程序线程得以继续,许多 JVM 实现的垃圾收集机制对多 CPU 的机器环境进行优化,通过同步来实现垃圾收集线程和应用程序线程的并发,使程序获得很好的总体性能。

 

设置虚拟机参数

通过设置虚拟机参数来配置垃圾收集器的行为和堆中不同区的大小分配。不同虚拟机的实现,参数选项不尽相同。IBM J9 虚拟机在 IBM 的从移动设备到企业解决方案中广泛的被使用,本文关于虚拟机选项参数的设定均基于 IBM 的 J9。

了解了垃圾收集以及它对性能的影响后,我们可以根据应用程序的特点来设置 GC 的策略进行有效的优化。相关参数是 -Xgcpolicy:[optthruput | optavgpause | gencon | subpool]

  • -Xgcpolicy:optthruput ,针对吞吐量优化,这是虚拟机默认的 GC 策略,适用于两种极端情况:应用需要尽可能快的在短时间内运行结束,或应用长时间运行,且运行过程中的吞吐量没有比较固定的大小和分布;
  • -Xgcpolicy:optavgpause ,针对 GC 导致的停顿优化,通过并发地执行一部分垃圾收集,在高吞吐量和短 GC 停顿之间进行折中。应用程序停顿的时间更短。适用于应用具有比较规则和突发的吞吐量周期分布;
  • -Xgcpolicy:gencon ,分代并发进行 GC,以不同方式处理短期存活的对象和长期存活的对象。采用这种策略时,具有许多短期存活对象的应用程序会表现出更短的停顿时间,同时仍然产生很好的吞吐量;
  • -Xgcpolicy:subpool ,子池优化,采用与默认策略相似的算法,但是采用一种比较适合多处理器计算机的分配策略。适用于在多核环境下运行的具有较高对象创建速率的多线程应用。

除了设置 GC 策略,最常设置的堆大小参数有:-Xms ,设置堆的初始大小;-Xmx ,设置堆空间的最大值;-Xmn ,设置年轻代空间大小;-Xmo ,设置年老代空间大小。程序员需要根据实际的机器环境和应用本身的特点来设置合理的值。


容易忽视的设计、编程原则和习惯

对虚拟机工作机制的了解能够使我们有把握写出更优雅、更高效的 Java 代码。下面是几条值得参考的设计、编程原则和习惯。

  • 及时更新虚拟机。

    除了由于某些产品兼容性的需要必须使用过去某个虚拟机版本外,建议将开发环境和最终产品部署的虚拟机运行时环境要求更新至最新版本。最新 的版本意味着最新的 API,更好的实现优化。这一点对嵌入式 Java(Java ME 和 Java Card)并不适用,随着移动或智能设备的发行,虚拟机就已经固化在其中,而新发布的虚拟机版本不能像在 EE 和 SE 安装的服务器和 PC 机一样,轻松进行安装。部分移动设备可以通过更新固件和操作系统程序来实现 VM 的版本更新。

  • 良好的面向对象设计和架构,应用设计模式。

    这点对于 Java 应用的性能、重用和可维护性尤为重要,设计模式是由大师们总结出的解决典型问题的通用架构,用对象来描述问题域,用设计模式来组织对象之间的行为。在设计 和解决局部问题时,首先要看看抽象出来的问题是否和某个设计模式的目标问题一致。此外,尽可能多的了解虚拟机所支持的 API,看所需的功能是否已有现成的实现可供调用,虚拟机平台实现的 API 大都具有良好的性能。

  • 关心 Java 栈。

    前面了解到,对于基于栈的 Java 虚拟机,方法的调用和执行伴随着压栈和出栈操作。每个线程有各自独立的栈,由虚拟机来管理栈的大小,但我们应该对它的大小有个概念。栈的大小是把双刃剑, 如果太小,可能会导致栈溢出,特别是在该线程内有递归、大的循环时出现溢出的可能性更大,如果过大,就会影响到可创建栈的数量,如果是多线程的应用,就会 导致内存溢出。通过 -Xss 可以设置 Java 栈的最大值,默认值为 256K 。不建议设置该选项为其他值,好的方案是,通过优化程序来减少递归层数、避免过大的循环、减少方法的调用层次,让你的程序尽量“扁平”,用尽可能好的对象间的关系来取代少数对象间深层次的方法调用。

  • 加强对象管理,不放任自流。

    过分依赖垃圾收集有时候会出现严重的性能问题,特别对于在程序运行中伴随着大量大对象创建的情况。好的习惯是显式的释放不用对象的引用, 在下一垃圾收集周期中被回收,这一点常常被 Java 程序员忽视,遗留的引用会导致 GC 无法回收这些逻辑上消亡的对象,看下面代码示例:



    清单 3. Java 实现的栈
    						
     public class Stack { 
      private static final int MAXLEN = 10; 
      private Object stk[] = new Object[MAXLEN]; 
      private int stkp = -1; 
    
      public void push(Object p) { 
        stk[++stkp] = p; 
      } 
     
      public Object pop1
    () { 
        return stk[stkp--]; 
      } 
      
      public Object pop2
    () { 
        Object p = stk[stkp]; 
        stk[stkp--] = null;
    
        return p; 
      } 
     }  
    

    示例代码是一个栈结构,栈中存储对象引用,容量为 10,stkp 是栈顶指针,push 方法将对象压入栈中,pop1 和 pop2 弹出栈顶对象。pop1 直接将对象弹出,该对象可能被其它对象使用之后立刻释放,而栈中仍有指向该对象的引用,由于栈可能在程序中长久存在,所以导致弹出的对象不能被回收。 pop2 方法在弹出对象前,将栈原来持有的对象引用置空释放,从而使弹出的对象彻底与栈脱离关系而不影响 GC。对于在程序运行中要大量创建和释放的对象,加强管理是很好的习惯,使用对象池机制是很好的解决方案,根据需要在对象池中创建一批对象,将不用的对象 放回池中,待下次取出使用,这也大大节省了对象的反复创建和销毁时间。



    清单 4. Java 对象池代码
    				
     import java.util.HashMap; 
     import java.util.LinkedHashSet; 
    
     public class ObjectFactory { 
    
        /** A counter for counting the number of objects in use. */ 
        private static int objInUse = 0; 
    
        /** A counter for counting the number of objects in pool. */ 
        private static int objInPool = 0; 
    
        /** The object pool. */ 
        private static HashMap objectPool = new HashMap(); 
    
        /** The corresponding object pool for a specific class. */ 
        private static LinkedHashSet subObjPool; 
    
        /** Generate object for use */ 
        public synchronized static Object generate(String className) { 
    
            Object retObj = null; 
    
            subObjPool = (LinkedHashSet) objectPool.get(className); 
    
            if (subObjPool != null && subObjPool.size() < 0) { 
    
                retObj = subObjPool.iterator().next(); 
                subObjPool.remove(retObj); 
                objInPool--; 
    
            } else { 
    
                try { 
    
                    retObj = newObj(className); 
    
                } catch (InstantiationException ie) { 
                    return null; 
                } catch (IllegalAccessException iae) { 
                    return null; 
                } catch (ClassNotFoundException cnfe) { 
                    return null; 
                } 
            } 
    
            objInUse++; 
    
            return retObj; 
    	 } 
    
        public synchronized static void drop(Object freeObject) { 
    
            if (freeObject != null) { 
    
                subObjPool = (LinkedHashSet) objectPool.get(className); 
    
                if (subObjPool == null) { 
                    subObjPool = new LinkedHashSet(); 
                    objectPool.put(className, subObjPool); 
                } 
    
                if (!subObjPool.contains(freeObject)) { 
                    subObjPool.add(freeObject); 
                    objInPool++; 
                    objInUse--; 
                } 
    
            } 
        } 
    
        /** Counts the number of objects which are in use now. */ 
        public static int countObjectInUse() { 
            return objInUse; 
        } 
    
        /** Checks the current size of the object pool. */ 
        public static int checkPoolSize() { 
            return objInPool; 
        } 
    
        /** New object for class name. */ 
        private static Object newObj(String className) 
    	    throws InstantiationException, IllegalAccessException, 
                ClassNotFoundException { 
    
            Object obj = Class.forName(className).newInstance(); 
            return obj; 
        } 
     } 
    


Java Profiler 工具

Java Profiler 是采用 JMX(Java Management Extensions,Java 资源管理框架)或 JVMPI(Java Virtual Machine Profiler Interface,Java 虚拟机监视程序接口)实现的对 Java 虚拟机中的资源、应用程序对象等进行监试的一类工具。Profiler 工具主要可以监视对象分配和回收、堆空间、线程运行、线程死锁、网络状态等。这为 Java 程序员进行性能分析提供了入手点,通过对程序运行时的状态分析,可以快速的定位问题,从而着手优化。Java Profiler 工具是分析 Java 程序性能的好帮手,但归根结底,性能的提高还依赖于程序员对 Java 虚拟机有一定了解,在此基础上遵循良好的设计和开发原则。这也是 Java 程序员成为真正高手的必由之路。

关于如何使用 profiler 工具,读者可参考相关资源进行深入研究,常用的 Java Profiler 工具有:

  • JConsole ,虚拟机 SDK 自带工具,安装好 Java SDK 后,在 /bin 目录下启动;
  • Eclipse TPTP(Test and Performance Tools Platform) 是由 Eclipse.org 顶级项目提供的一个测试与性能监测方面的工具插件;
  • Netbeans Profiler ,Sun 内置于 Netbeans 中 profiler,方便用 Netbeans 开发时使用;
  • Visual VM ,最初,Sun 随 JDK 6 Update 7 发布的 profiler,Visual Vm 包含 JConsole,同时界面更加美观且易于使用。

结束语

本文从 Java 虚拟机的视角出发,剖析了与 Java 应用程序性能相关的因素,通过总结的一些程序员容易忽视的设计、编程原则和习惯,希望对帮助广大 Java 程序员提高性能优化意识和水平有所帮助。

分享到:
评论

相关推荐

    实战Java虚拟机——JVM故障诊断与性能优化 pdf

    《实战Java虚拟机——JVM故障诊断与性能优化》内容简介:随着越来越多的第三方语言(Groovy、Scala、JRuby等)在Java虚拟机上运行,Java也俨然成为一个充满活力的生态圈。本书将通过200余示例详细介绍Java虚拟机中的...

    实战Java虚拟机_JVM故障诊断与性能优化

    实战Java虚拟机_JVM故障诊断与性能优化 JVM故障诊断与性能优化 JVM调优

    阿里巴巴Java性能调优实战(2021-2022华山版)+Java架构核心宝典+性能优化手册100技巧.rar

    性能优化手册是一套java性能学习研究小技巧,包含内容:Java性能优化、JVM性能优化、服务器性能优化、数据库性能优化、前端性能优化等。 内容包括但不限于: String 性能优化的 3 个小技巧 HashMap 7 种遍历方式...

    实战JAVA虚拟机 JVM故障诊断与性能优化.pdf

    实战JAVA虚拟机 JVM故障诊断与性能优化.pdf (无书签.低分放送) 实战JAVA虚拟机 JVM故障诊断与性能优化.pdf (无书签.低分放送) 实战JAVA虚拟机 JVM故障诊断与性能优化.pdf (无书签.低分放送)

    实战Java虚拟机——JVM故障诊断与性能优化.pdf

    《实战Java虚拟机——JVM故障诊断与性能优化》是一本深入探讨Java开发中的关键环节——Java虚拟机(JVM)的专著。本书聚焦于实际应用中的问题解决和性能调优,对于Java开发者和系统管理员来说,是提升技术水平的重要...

    4本高清中文版Java性能优化经典书籍

    Java性能优化是IT行业中至关重要的一个领域,尤其是在大型企业级应用和互联网服务中,高效的Java代码能够显著提升系统运行效率,降低服务器资源消耗。以下是对这四本经典书籍中的核心知识点的详细介绍: 1. **...

    实战JAVA虚拟机 JVM故障诊断与性能优化

    《实战JAVA虚拟机—JVM故障诊断与性能优化》是一本深入探讨Java虚拟机(JVM)技术的书籍,旨在帮助开发者和系统管理员诊断并优化JVM相关的性能问题。本书内容丰富,涵盖了大量的实践案例,使得即便是初学者也能理解...

    java jvm及性能优化_javajvm优化_Java性能分析_

    以下是对"Java JVM及性能优化"和"Java性能分析"的详细阐述: 一、JVM结构与工作原理 1. 类装载器:负责加载类文件,确保在运行时能找到对应的类。 2. 运行数据区:包括方法区、堆、栈、本地方法栈和程序计数器。...

    实战JAVA虚拟机 (JVM故障诊断与性能优化)【含源码】

    《实战JAVA虚拟机 (JVM故障诊断与性能优化)》是一本深度剖析JVM的实践指南,旨在帮助读者掌握JVM的内部工作机制,提升故障排查和性能调优的能力。本书可与周志明的《深入理解JAVA虚拟机》相媲美,提供了丰富的源码...

    Java性能优化指南:JVM调优技巧与实践

    随着Java技术的不断发展,新的调优方法和工具将不断涌现,帮助开发者更有效地优化JVM性能。 JVM性能调优是一个多方面的任务,涉及JVM配置、垃圾回收策略、内存管理、线程使用等多个方面。通过采用合适的调优技巧和...

    实战Java虚拟机——JVM故障诊断与性能优化

    《实战Java虚拟机——JVM故障诊断与性能优化》是一本深入探讨Java开发人员和运维人员必备技能的书籍。本书作者葛一鸣以其丰富的实战经验,详细阐述了JVM(Java Virtual Machine)的工作原理,以及如何有效地进行故障...

    Java性能优化手册100技巧 中文PDF最新版

    性能优化手册是一套java性能学习研究小技巧,包含内容:Java性能优化、JVM性能优化、服务器性能优化、数据库性能优化、前端性能优化等。 内容包括但不限于: String 性能优化的 3 个小技巧 HashMap 7 种遍历方式...

    实战Java虚拟机 JVM故障诊断与性能优化 葛一鸣

    《实战Java虚拟机 JVM故障诊断与性能优化》是由葛一鸣编著的一本专业书籍,主要探讨了如何在实际工作中解决Java虚拟机(JVM)的相关问题,以及如何进行性能调优。书中涵盖了许多关键的知识点,让我们一一展开讨论。 ...

    Java虚拟机-jvm故障诊断与性能优化-源码

    在《实战Java虚拟机——JVM故障诊断与性能优化》一书中,作者深入探讨了如何对JVM进行故障排查和性能调优,通过源码分析来帮助读者理解其内部工作原理。下面我们将根据书中的主题,详细阐述相关的知识点。 1. **JVM...

    大话JAVA性能优化

    但根据标题《大话JAVA性能优化》和描述“虽然有些地方可能过时,但是还是可以一读”以及标签“java 优化”,可以推断出书籍内容可能围绕Java编程语言的性能优化相关知识。基于这些信息,我们可以构建关于Java性能...

    java性能优化教程

    总的来说,Java性能优化涉及代码质量、JVM配置、并发处理、IO操作等多个方面。通过深入理解和实践,我们可以打造出更高效、更稳定的Java应用程序。这个"JAVA优化编程"PDF教程将引导你逐步掌握这些核心技巧,助你在...

    实战JAVA虚拟机 JVM故障诊断与性能优化.rar

    《实战JAVA虚拟机 JVM故障诊断与性能优化》是一本深度探讨Java虚拟机(JVM)的专著,旨在帮助开发者解决实际工作中遇到的JVM相关问题,提升系统的性能表现。通过对JVM内部机制的深入理解,我们可以更有效地调试、...

    Java性能优化实战21 讲 视频课程-网盘链接提取码下载 .txt

    对 Java 工程师而言,性能优化能力决定了你能否进入大厂或成为一名高级工程师。但性能优化的能力却极难提升,如果你缺乏正确的方法论和实战演练,则很容易事倍功半。 视频大小:1.2G

Global site tag (gtag.js) - Google Analytics