文章分类 -  极客时间

上一页 1 ··· 11 12 13 14 15 16 17 18 19 ··· 45 下一页
摘要:我们经常会遇见Java语言较难表达,甚至是无法表达的应用场景。比如我们希望使用汇编语言(如X86_64的SIMD指令)来提升关键代码的性能;再比如,我们希望调用Java核心类库无法提供的,某个体系架构或者操作系统特有的功能。 在这种情况下,我们往往会牺牲可移植性,在Java代码中调用C/C++代码( 阅读全文
posted @ 2023-01-10 10:07 易先讯 阅读(10) 评论(0) 推荐(0)
摘要:今天我们来继续了解Java虚拟机的监控及诊断工具。 eclipse MAT 在上一篇中,我介绍了jmap工具,它支持导出Java虚拟机堆的二进制快照。eclipse的MAT工具便是其中一个能够解析这类二进制快照的工具。 MAT本身也能够获取堆的二进制快照。该功能将借助jps列出当前正在运行的Java 阅读全文
posted @ 2023-01-10 10:06 易先讯 阅读(11) 评论(0) 推荐(0)
摘要:今天,我们来一起了解一下JDK中用于监控及诊断工具。本篇中我将使用刚刚发布的Java 11版本的工具进行示范。 jps 你可能用过ps命令,打印所有正在运行的进程的相关信息。JDK中的jps命令(帮助文档)沿用了同样的概念:它将打印所有正在运行的Java进程的相关信息。 在默认情况下,jps的输出信 阅读全文
posted @ 2023-01-10 10:06 易先讯 阅读(7) 评论(0) 推荐(0)
摘要:今天我们来继续学习基准测试框架JMH。 @Fork和@BenchmarkMode 在上一篇的末尾,我们已经运行过由JMH项目编译生成的jar包了。下面是它的输出结果: $ java -jar target/benchmarks.jar ... # JMH version: 1.21 # VM ver 阅读全文
posted @ 2023-01-10 10:05 易先讯 阅读(4) 评论(0) 推荐(0)
摘要:今天我们来聊聊性能基准测试(benchmarking)。 大家或许都看到过一些不严谨的性能测试,以及基于这些测试结果得出的令人匪夷所思的结论。 static int foo() { int i = 0; while (i < 1_000_000_000) { i++; } return i; } 举 阅读全文
posted @ 2023-01-10 10:05 易先讯 阅读(9) 评论(0) 推荐(0)
摘要:注解(annotation)是Java 5引入的,用来为类、方法、字段、参数等Java结构提供额外信息的机制。我先举个例子,比如,Java核心类库中的@Override注解是被用来声明某个实例方法重写了父类的同名同参数类型的方法。 package java.lang; @Target(Element 阅读全文
posted @ 2023-01-10 10:04 易先讯 阅读(9) 评论(0) 推荐(0)
摘要:在上一篇的实践环节中,我给你留了一个题目:如何进一步优化下面这段代码。 void foo(byte[] dst, byte[] src) { for (int i = 0; i < dst.length - 4; i += 4) { dst[i] = src[i]; dst[i+1] = src[i 阅读全文
posted @ 2023-01-10 10:03 易先讯 阅读(12) 评论(0) 推荐(0)
摘要:在许多应用程序中,循环都扮演着非常重要的角色。为了提升循环的运行效率,研发编译器的工程师提出了不少面向循环的编译优化方式,如循环无关代码外提,循环展开等。 今天,我们便来了解一下,Java虚拟机中的即时编译器都应用了哪些面向循环的编译优化。 循环无关代码外提 所谓的循环无关代码(Loop-invar 阅读全文
posted @ 2023-01-10 10:03 易先讯 阅读(10) 评论(0) 推荐(0)
摘要:在上一篇文章中,我介绍了逃逸分析,也介绍了基于逃逸分析的优化方式锁消除、栈上分配以及标量替换等内容。 其中的标量替换,可以看成将对象本身拆散为一个个字段,并把原本对对象字段的访问,替换为对一个个局部变量的访问。 class Foo { int a = 0; } static int bar(int 阅读全文
posted @ 2023-01-10 09:55 易先讯 阅读(4) 评论(0) 推荐(0)
摘要:我们知道,Java中Iterable对象的foreach循环遍历是一个语法糖,Java编译器会将该语法糖编译为调用Iterable对象的iterator方法,并用所返回的Iterator对象的hasNext以及next方法,来完成遍历。 public void forEach(ArrayList<O 阅读全文
posted @ 2023-01-10 09:55 易先讯 阅读(4) 评论(0) 推荐(0)
摘要:前不久,有同学问我,String.indexOf方法和自己实现的indexOf方法在字节码层面上差不多,为什么执行效率却有天壤之别呢?今天我们就来看一看。 public int indexOf(String str) { if (coder() == str.coder()) { return is 阅读全文
posted @ 2023-01-10 09:54 易先讯 阅读(11) 评论(0) 推荐(0)
摘要:在上一篇中,我举的例子都是静态方法调用,即时编译器可以轻易地确定唯一的目标方法。 然而,对于需要动态绑定的虚方法调用来说,即时编译器则需要先对虚方法调用进行去虚化(devirtualize),即转换为一个或多个直接调用,然后才能进行方法内联。 即时编译器的去虚化方式可分为完全去虚化以及条件去虚化(g 阅读全文
posted @ 2023-01-10 09:54 易先讯 阅读(17) 评论(0) 推荐(0)
摘要:在前面的篇章中,我多次提到了方法内联这项技术。它指的是:在编译过程中遇到方法调用时,将目标方法的方法体纳入编译范围之中,并取代原方法调用的优化手段。 方法内联不仅可以消除调用本身带来的性能开销,还可以进一步触发更多的优化。因此,它可以算是编译优化里最为重要的一环。 以getter/setter为例, 阅读全文
posted @ 2023-01-10 09:53 易先讯 阅读(12) 评论(0) 推荐(0)
摘要:在前面的篇章中,有不少同学反馈对Java字节码并不是特别熟悉。那么今天我便来系统性地介绍一遍Java字节码。 操作数栈 我们知道,Java字节码是Java虚拟机所使用的指令集。因此,它与Java虚拟机基于栈的计算模型是密不可分的。 在解释执行过程中,每当为Java方法分配栈桢时,Java虚拟机往往需 阅读全文
posted @ 2023-01-10 09:53 易先讯 阅读(15) 评论(0) 推荐(0)
摘要:在上一章中,我利用了程序控制流图以及伪代码,来展示即时编译器中基于profile的优化。不过,这并非实际的优化过程。 1. 中间表达形式(IR) 在编译原理课程中,我们通常将编译器分为前端和后端。其中,前端会对所输入的程序进行词法分析、语法分析、语义分析,然后生成中间表达形式,也就是IR(Inter 阅读全文
posted @ 2023-01-10 09:52 易先讯 阅读(6) 评论(0) 推荐(0)
摘要:今天我们来继续讲解Java虚拟机中的即时编译。 Profiling 上篇提到,分层编译中的0层、2层和3层都会进行profiling,收集能够反映程序执行状态的数据。其中,最为基础的便是方法的调用次数以及循环回边的执行次数。它们被用于触发即时编译。 此外,0层和3层还会收集用于4层C2编译的数据,比 阅读全文
posted @ 2023-01-10 09:52 易先讯 阅读(8) 评论(0) 推荐(0)
摘要:在专栏的第一篇中,我曾经简单地介绍过即时编译。这是一项用来提升应用程序运行效率的技术。通常而言,代码会先被Java虚拟机解释执行,之后反复执行的热点代码则会被即时编译成为机器码,直接运行在底层硬件之上。 今天我们便来详细剖析一下Java虚拟机中的即时编译。 分层编译模式 HotSpot虚拟机包含多个 阅读全文
posted @ 2023-01-10 09:52 易先讯 阅读(12) 评论(0) 推荐(0)
摘要:在前面的篇章中,我们多次提到了Java语法和Java字节码的差异之处。这些差异之处都是通过Java编译器来协调的。今天我们便来列举一下Java编译器的协调工作。 自动装箱与自动拆箱 首先要提到的便是Java的自动装箱(auto-boxing)和自动拆箱(auto-unboxing)。 我们知道,Ja 阅读全文
posted @ 2023-01-10 09:51 易先讯 阅读(10) 评论(0) 推荐(0)
摘要:在Java程序中,我们可以利用synchronized关键字来对程序进行加锁。它既可以用来声明一个synchronized代码块,也可以直接标记静态方法或者实例方法。 当声明synchronized代码块时,编译而成的字节码将包含monitorenter和monitorexit指令。这两种指令均会消 阅读全文
posted @ 2023-01-10 09:51 易先讯 阅读(11) 评论(0) 推荐(0)
摘要:我们先来看一个反常识的例子。 int a=0, b=0; public void method1() { int r2 = a; b = 1; } public void method2() { int r1 = b; a = 2; } 这里我定义了两个共享变量a和b,以及两个方法。第一个方法将局部 阅读全文
posted @ 2023-01-10 09:50 易先讯 阅读(13) 评论(0) 推荐(0)

上一页 1 ··· 11 12 13 14 15 16 17 18 19 ··· 45 下一页