2022年4月

Java 性能优化视频笔记

https://thestrangeloop.com/2017/the-performance-engineers-guide-to-java-hotspot-virtual-machines-execution-engine.html
这个视频其实和她的那本书基本是一致的, 加了些那年比较新的东西.

  1. JDK 是我们开发用的开发工具集, 里面包含 JRE 和一些工具, 比如 jps, cmd, JVisualVM 等;
  2. JRE 是 Java 运行时引擎, 是 Java 代码跑起来的必要设施. 它处于用户代码和 OS 之间;
  3. API 是我们的代码和 JRE 之间的接口;
  4. JRE 里面主要的功能是 编译 和 内存管理, 所以 JRE 层面的优化主要是编译和内存管理(heap)方面;
  5. Java 的内存管理主要是管理 内存的分配和内存的回收 -> 内存管理算法 -> CMS, G1, etc;
  6. 编译分为 静态编译 和 动态运行时编译;
  7. JIT 优化: 提前编译, 分层编译, 基于已搜集信息的编译(profile-based), 启发式编译;
  8. Java 代码是先翻译(javac 成 class 文件字节码)然后再部分编译(JIT);
  9. JRE(运行时)的主要目的就是把字节码转换成操作系统 native 代码;
  10. 内存分配-> 快速分配 -> TLAB & PLAB;
  11. 锁: 偏向锁, 轻量锁, 锁膨胀, 锁消除;
  12. 代码: inline, 逃逸分析, 代码消除, 栈上分配, 寄存器分配;
  13. String 实现的优化 itern();

MAC 的 PATH 环境变量

在 MAC 上工作, 竟然遇到要更改 PATH 环境变量的情况. 比如有的 Java 工程是基于 JDK8 的, 有的是基于 JDK11 的, 所以经常要改这个变量. 那么我们看到的 PATH 环境变量是从哪里来的, 那些配置文件会改这些 PATH 值呢?

首先, 我们先看下当前的 PATH 变量:

~ xiatian$ echo $PATH
/usr/local//Cellar/curl/7.80.0_1/bin/:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/Wireshark.app/Contents/MacOS:/Users/xiatian/work/tools:/Applications/Visual\ Studio\ Code.app/Contents/Resources/app/bin/

这里面有好多路径, 那么我们好奇当系统启动的过程中, 最初的 PATH 是什么呢?

  1. MAC 上最初的 PATH 是从 /etc/paths 文件读的:

    ~ xiatian$ cat /etc/paths
    /usr/local/bin
    /usr/bin
    /bin
    /usr/sbin
    /sbin
  2. 然后, 它会把 /etc/path.d 里面的路径逐个添加到后面, 比如我们可以看到我的 wireshark 路径在上面的 PATH 里:

    ~ xiatian$ ls -l /etc/paths.d/
    total 8
    -rw-r--r--  1 root  wheel  43 Oct 19  2017 Wireshark
    ~ xiatian$ cat /etc/paths.d/Wireshark
    /Applications/Wireshark.app/Contents/MacOS
  3. 在个人的 home 目录, 还有2个文件会影响 PATH 的值: .bash_profile & .bash_rc. 他们的区别是: 当一个 shell 是 login shell 的时候, 它会先执行 .bash_profile, 当是一个非 login 交互式 shell 的时候, 它执行 .bashrc. 但是在 MAC 上, 默认都是 login shell, 所以应该都执行. 来源于这个问答. 我试过了自带的 Terminal 和 安装的 iterm, 发现我的 MAC 都不是这么玩的.
  4. 我本地是执行的 ~/.profile. 查看 bash 的 man, 你会在 INVOCATION section 看到具体的配置执行顺序:

    ~ xiatian$ man bash
    When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file  /etc/profile,  if that  file exists.  After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable.  The --noprofile option may be used when the shell is started to inhibit this behavior.
    When an interactive shell that is not a login shell is started, bash reads and executes commands from ~/.bashrc, if that file exists.  This may be inhibited by using the --norc option.  The --rcfile file option will force bash to read and execute commands from file instead of ~/.bashrc.

所以, 只要仔细阅读 man bash 的内容, 你就知道 PATH 是怎么变化的啦.