极客时间已完结课程限时免费阅读

79 | 程序员练级攻略:Java底层知识

79 | 程序员练级攻略:Java底层知识-极客时间

79 | 程序员练级攻略:Java底层知识

讲述:杨超

时长07:55大小7.22M

你好,我是陈皓,网名左耳朵耗子。
前两篇文章分享的是系统底层方面的内容,今天我们进入高手成长篇的第二部分——Java 底层知识。

Java 字节码相关

首先,Java 最黑科技的玩法就是字节码编程,也就是动态修改或是动态生成 Java 字节码。Java 的字节码相当于汇编,其中的一些细节你可以从下面的这几个教程中学习。
Java Zone: Introduction to Java Bytecode ,这篇文章图文并茂地向你讲述了 Java 字节码的一些细节,是一篇很不错的入门文章。
IBM DeveloperWorks: Java bytecode ,虽然这篇文章很老了,但是这篇文章是一篇非常好的讲 Java 字节码的文章。
Java Bytecode and JVMTI Examples,这是一些使用 JVM Tool Interface 操作字节码的比较实用的例子。包括方法调用统计、静态字节码修改、Heap Taggin 和 Heap Walking。
当然,一般来说,我们不使用 JVMTI 操作字节码,而是用一些更好用的库。这里有三个库可以帮你比较容易地做这个事。
asmtools - 用于生产环境的 Java .class 文件开发工具。
Byte Buddy - 代码生成库:运行时创建 Class 文件而不需要编译器帮助。
Jitescript - 和 BiteScript 类似的字节码生成库。
就我而言,我更喜欢 Byte Buddy,它在 2015 年还获了 Oracle 的 “Duke’s Choice”大奖,其中说 Byte Buddy 极大地发展了 Java 的技术。
使用字节码编程可以玩出很多高级玩法,最高级的还是在 Java 程序运行时进行字节码修改和代码注入。听起来是不是一些很黑客,也很黑科技的事?是的,这个方式使用 Java 这门静态语言在运行时可以进行各种动态的代码修改,而且可以进行无侵入的编程。
比如, 我们不需要在代码中埋点做统计或监控,可以使用这种技术把我们的监控代码直接以字节码的方式注入到别人的代码中,从而实现对实际程序运行情况进行统计和监控。如果你看过我的《编程范式游记》,你就知道这种技术的威力了,其可以很魔法地把业务逻辑和代码控制分离开来。
要做到这个事,你还需要学习一个叫 Java Agent 的技术。Java Agent 使用的是 “Java Instrumentation API”,其主要方法是实现一个叫 premain() 的方法(嗯,一个比 main() 函数还要超前执行的 main 函数),然后把你的代码编译成一个 jar 文件。
在 JVM 启动时,使用这样的命令行来引入你的 jar 文件:java -javaagent:yourAwesomeAgent.jar -jar App.jar。更为详细的文章你可以参看:“Java Code Geeks: Java Agents”,你还可以看一下这个示例项目:jvm-monitoring-agent 或是 EntryPointKR/Agent.java。如果想用 ByteBuddy 来玩,你可以看看这篇文章 “通过使用 Byte Buddy,便捷地创建 Java Agent”。如果你想学习如何用 Java Agent 做监控,你可以看一下这个项目 Stage Monitor

JVM 相关

接下来讲讲 Java 底层知识中另一个非常重要的内容——JVM。
说起 JVM,你有必要读一下 JVM 的规格说明书,我在这里放一个 Java 8 的, The Java Virtual Machine Specification Java SE 8 Edition 。对于规格说明书的阅读,我认为是系统了解 JVM 规范的最佳文档,这个文档可以让你对于搞不清楚或是诡异的问题恍然大悟。关于中文翻译,有人在 GitHub 上开了个 Repo - “java-virtual-machine-specification”。
另外,也推荐一下 JVM Anatomy Park JVM 解剖公园,这是一个系列的文章,每篇文章都不长,但是都很精彩,带你一点一点地把 JVM 中的一些技术解开。
学习 Java 底层原理还有 Java 的内存模型,官方文章是 JSR 133。还有马里兰大学的威廉·皮尤(William Pugh)教授收集的和 Java 内存模型相关的文献 - The Java Memory Model ,你可以前往浏览。
对于内存方面,道格·利(Doug Lea)有两篇文章也是很有价值的。
The JSR-133 Cookbook for Compiler Writers,解释了怎样实现 Java 内存模型,特别是在考虑到多处理器(或多核)系统的情况下,多线程和读写屏障的实现。
Using JDK 9 Memory Order Modes,讲了怎样通过 VarHandle 来使用 plain、opaque、release/acquire 和 volatile 四种共享内存的访问模式,并剖析了底层的原理。
垃圾回收机制也是需要好好学习的,在这里推荐一本书 《The Garbage Collection Handbook》,在豆瓣上的得分居然是 9.9(当然,评价人数不多)。这本书非常全面地介绍了垃圾收集的原理、设计和算法。但是这本书也是相当难啃的。中文翻译《垃圾回收算法手册》翻译得很一般,有人说翻译得很烂。所以,如果可能,还是读英文版的。如果你对从事垃圾回收相关的工作有兴趣,那么你需要好好看一下这本书。
当然,更多的人可能只需要知道怎么调优垃圾回收, 那么推荐读读 Garbage Collection Tuning Guide ,它是 Hotspot Java 虚拟机的垃圾回收调优指南,对你很有帮助。
Quick Tips for Fast Code on the JVM 也是一篇很不错的文章,里面有写出更快的 Java 代码的几个小提示,值得一读。

小结

好了,总结一下今天学到的内容。Java 最黑科技的玩法就是字节码编程,也就是动态修改或是动态生成 Java 字节码。Java 的字节码相当于汇编,学习其中的细节很有意思,为此我精心挑选了 3 篇文章,供你学习。我们一般不使用 JVMTI 操作字节码,而是用一些更好用的库,如 asmtools、Byte Buddy 和 BiteScript 等。使用字节码编程可以玩出很多高级玩法,其中最高级的玩法是在 Java 程序运行时进行字节码修改和代码注入。同时,我介绍了 Java Agent 技术,帮助你更好地实现这种高级玩法。
JVM 也是学习 Java 过程中非常重要的一部分内容。我推荐阅读一下 JVM 的规格说明书,我认为,它是系统了解 JVM 规范的最佳文档,可以让你对于搞不清楚或是诡异的问题恍然大悟。同时推荐了 JVM Anatomy Park 系列文章,也非常值得一读。
随后介绍的是 Java 的内存模型和垃圾回收机制,尤其给出了如何调优垃圾回收方面的资料。这些内容都很底层,但也都很重要。对于想成为高手的你来说,还是有必要花时间来啃一啃的。
下篇文章是数据库方面的内容,我们将探讨各种类型的数据库,非常有意思。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
分享给需要的人,Ta购买本课程,你将得29
生成海报并分享

赞 16

提建议

上一篇
78 | 程序员练级攻略:异步I/O模型和Lock-Free编程
下一篇
80 | 程序员练级攻略:数据库
unpreview
 写留言

精选留言(28)

  • 二进制之路
    2018-07-19
    有同学认为这种介绍文章没用,一大堆引用。我觉得吧,这文章价值很大。如果只是要写一篇关于字节码或JVM的详细使用,那很多书籍或网站可能有了,反而不值得写。耗子叔这系列文章,在我看来很有大局观,自顶向下梳理了各种技术脉络。授人以渔其实更重要,好的老师是给你指出明路,让你少走弯路,而不是给你讲解几道题。不过这也许要工作几年后才能更深刻的体会到吧,这些总结的资源是一笔财富,至少不用走弯路,可以有选择性的去挑选适合你的认为有价值有兴趣的内容去学习。
    展开

    作者回复: 谢谢理解

    101
  • 吃桔子的攻城狮
    2018-08-03
    第一次评论。这个专栏看了这么久,第一次觉得有必要说几句,这种风格的专栏真的非常赞。看到有些同学说链接太多缺少耗子哥自己的东西,我想说这个系列随便一篇文章拿出来,如果纯自己写都能单独写成一个系列甚至一本书。这就像重复造轮子,明明已经有了优秀的文献资料,为什么要重新写一套?相反,能把这些优质资源做整合,串联,归纳,提供学习的路径和思路才是受益无穷的! 有同学说这些都是网上可以找到的,那不妨请想一下,如果只给你本系列某篇文章的题目,凭自己你真的可以找得到这些资料吗?不会陷入现在互相抄来抄去的劣质博客里迷惘困惑,百思不得其解吗? 支持这种风格,我认为订阅专栏的钱花的很超值!
    展开

    作者回复: 谢谢

    共 2 条评论
    45
  • 怪盗キッド
    2018-07-03
    Hi,我利用ASM写了一个简单、快速且无侵入的Java方法监控工具MyPerf4J,通过JavaAgent方式对Java方法进行字节码注入,可以统计出方法的执行性能指标,包括RPS、Avg、TP50、TP90、TP99、TP999等,Github地址:https://github.com/ThinkpadNC5/MyPerf4J

    作者回复: 👍那些统计,你用到了蓄水池算法了吗?

    28
  • lion_fly
    2019-12-05
    看这么多书,耗子叔居然没有掉头发
    13
  • ruby
    2018-07-03
    皓哥,后面有大数据文章,怎么学spark.hadoop等吗?
    8
  • superryanguo
    2018-07-03
    java有必要单独抽一篇来讲吗?而且都是引用
    6
  • 待时而发
    2020-02-29
    耗子叔,实在是太厉害了,这种资源整合真的是服了,那天看你直播发现你头发还是那么多,这么多的东西你是怎么看完的.....太佩服了
    4
  • 鹤鸣
    2018-07-04
    C++程序员问个问题:怎样对一个已有的基于spring的项目优化性能?目前我这边首先要做的事情是测试出性能瓶颈,但是目前为止我还在使用那种很土的办法,纯体力活的那种,我觉得这个路子不大对头。
    4
  • ZYCHD(子玉)
    2018-07-03
    读耗子书的文章总给人带来新鲜的感觉。视野很开阔。前后穿插纵横千里!
    3
  • Rolin
    2018-07-03
    Android 程序猿好好学!
    2
  • 葛阳
    2018-07-03
    2
  • 货赛阔xliu
    2020-06-08
    左耳朵老师, Aleksey的那个blog叫JVM Anatomy Quarks,不是park是夸克。 我觉得他就是想对jvm做量子维度的分析。
    1
  • 土豆小小
    2020-04-28
    突然的感受,国外程序员的简历上都有很多底层语言,就很好奇他们在自己的项目中是如何涉及到这么多不同的技术
    1
  • CodeAllen
    2020-03-29
    打卡第79篇,感谢耗子叔
    1
  • 庞雨青_Alice
    2019-06-01
    非常感谢左耳皓哥的分享。 读精品的技术文章真是一件很爽快的事情。我个人是喜欢刨根究底的类型,之前在学习编程的过程中一直都没能找到多少成就感。现在看来一是没有找到最精品的文章,二是没有找到适合自己的方式。 这几天耐着性子慢慢读英文的文章,自己的英语能力也有所提高。 感谢皓哥🙏
    展开
    2
  • 2019-01-09
    恩,认同这种风格的文章,感觉很导师风格,指明路线自己去玩,每个人的收获取决于每个人的付出。
    1
  • 中山浪子
    2018-07-04
    耗叔有专门讲c++对象模型方面和内存分配的篇章嚒?
    1
  • 范特西
    2022-02-21
    耗子书文章点赞,现在计算机只是体系已经非常庞大。想要学习的人也会太多东西,容易东打一枪西打一枪。别人都是贩卖焦虑转我的快钱。耗子叔的东西提纲挈领,让人心里他是。更适合愿意沉下心来学习的人。我自己是平时在浩瀚的知识海洋中常常迷失,所以感谢大佬指点!
  • wxlbear
    2021-12-30
    能把老师提供的都消化掉,那绝对已经是很厉害的
  • 方勇(gopher)
    2021-11-30
    目前java监控采用agent注入的模式!