From b88e09ce859ba30e93602e7fe72842e988b0cb61 Mon Sep 17 00:00:00 2001 From: Guide Date: Tue, 14 Nov 2023 10:58:07 +0800 Subject: [PATCH] =?UTF-8?q?[docs=20update]=E5=AE=8C=E5=96=84JDK=E5=92=8CJR?= =?UTF-8?q?E=E5=AF=B9=E6=AF=94+=E5=81=8F=E5=90=91=E9=94=81JDK=E6=96=B0?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E7=A7=BB=E9=99=A4=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/database/redis/redis-questions-02.md | 10 ++++++---- docs/java/basis/java-basic-questions-01.md | 10 ++++++++++ docs/java/concurrent/java-concurrent-questions-02.md | 2 ++ docs/java/new-features/java14-15.md | 2 +- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/docs/database/redis/redis-questions-02.md b/docs/database/redis/redis-questions-02.md index 3634359a..04e9bc85 100644 --- a/docs/database/redis/redis-questions-02.md +++ b/docs/database/redis/redis-questions-02.md @@ -284,14 +284,16 @@ Lua 脚本同样支持批量操作多条命令。一段 Lua 脚本可以视作 简单来说,如果一个 key 对应的 value 所占用的内存比较大,那这个 key 就可以看作是 bigkey。具体多大才算大呢?有一个不是特别精确的参考标准: -- string 类型的 value 超过 1MB -- 复合类型(List、Hash、Set、Sorted Set 等)的 value 包含的元素超过 5000 个(对于复合类型的 value 来说,不一定包含的元素越多,占用的内存就越多)。 +- String 类型的 value 超过 1MB +- 复合类型(List、Hash、Set、Sorted Set 等)的 value 包含的元素超过 5000 个(不过,对于复合类型的 value 来说,不一定包含的元素越多,占用的内存就越多)。 + +![bigkey 判定标准](https://oss.javaguide.cn/github/javaguide/database/redis/bigkey-criterion.png) #### bigkey 是怎么产生的?有什么危害? bigkey 通常是由于下面这些原因产生的: -- 程序设计不当,比如直接使用 string 类型存储较大的文件对应的二进制数据。 +- 程序设计不当,比如直接使用 String 类型存储较大的文件对应的二进制数据。 - 对于业务的数据规模考虑不周到,比如使用集合类型的时候没有考虑到数据量的快速增长。 - 未及时清理垃圾数据,比如哈希中冗余了大量的无用键值对。 @@ -337,7 +339,7 @@ Biggest string found '"ballcat:oauth:refresh_auth:f6cdb384-9a9d-4f2f-af01-dc3f28 0 zsets with 0 members (00.00% of keys, avg size 0.00 ``` -从这个命令的运行结果,我们可以看出:这个命令会扫描(Scan) Redis 中的所有 key ,会对 Redis 的性能有一点影响。并且,这种方式只能找出每种数据结构 top 1 bigkey(占用内存最大的 string 数据类型,包含元素最多的复合数据类型)。然而,一个 key 的元素多并不代表占用内存也多,需要我们根据具体的业务情况来进一步判断。 +从这个命令的运行结果,我们可以看出:这个命令会扫描(Scan) Redis 中的所有 key ,会对 Redis 的性能有一点影响。并且,这种方式只能找出每种数据结构 top 1 bigkey(占用内存最大的 String 数据类型,包含元素最多的复合数据类型)。然而,一个 key 的元素多并不代表占用内存也多,需要我们根据具体的业务情况来进一步判断。 在线上执行该命令时,为了降低对 Redis 的影响,需要指定 `-i` 参数控制扫描的频率。`redis-cli -p 6379 --bigkeys -i 3` 表示扫描过程中每次扫描后休息的时间间隔为 3 秒。 diff --git a/docs/java/basis/java-basic-questions-01.md b/docs/java/basis/java-basic-questions-01.md index ebefbe84..faf5d850 100644 --- a/docs/java/basis/java-basic-questions-01.md +++ b/docs/java/basis/java-basic-questions-01.md @@ -68,6 +68,16 @@ JRE(Java Runtime Environment) 是 Java 运行时环境。它是运行已编 ![JDK 包含 JRE](https://oss.javaguide.cn/github/javaguide/java/basis/jdk-include-jre.png) +不过,从 JDK 9 开始,就不需要区分 JDK 和 JRE 的关系了,取而代之的是模块系统(JDK 被重新组织成 94 个模块)+ [jlink](http://openjdk.java.net/jeps/282) 工具 (随 Java 9 一起发布的新命令行工具,用于生成自定义 Java 运行时映像,该映像仅包含给定应用程序所需的模块) 。并且,从 JDK 11 开始,Oracle 不再提供单独的 JRE 下载。 + +在 [Java 9 新特性概览](https://javaguide.cn/java/new-features/java9.html)这篇文章中,我在介绍模块化系统的时候提到: + +> 在引入了模块系统之后,JDK 被重新组织成 94 个模块。Java 应用可以通过新增的 jlink 工具,创建出只包含所依赖的 JDK 模块的自定义运行时镜像。这样可以极大的减少 Java 运行时环境的大小。 + +也就是说,可以用 jlink 根据自己的需求,创建一个更小的 runtime(运行时),而不是不管什么应用,都是同样的 JRE。 + +定制的、模块化的 Java 运行时映像有助于简化 Java 应用的部署和节省内存并增强安全性和可维护性。这对于满足现代应用程序架构的需求,如虚拟化、容器化、微服务和云原生开发,是非常重要的。 + ### 什么是字节码?采用字节码的好处是什么? 在 Java 中,JVM 可以理解的代码就叫做字节码(即扩展名为 `.class` 的文件),它不面向任何特定的处理器,只面向虚拟机。Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以, Java 程序运行时相对来说还是高效的(不过,和 C、 C++,Rust,Go 等语言还是有一定差距的),而且,由于字节码并不针对一种特定的机器,因此,Java 程序无须重新编译便可在多种不同操作系统的计算机上运行。 diff --git a/docs/java/concurrent/java-concurrent-questions-02.md b/docs/java/concurrent/java-concurrent-questions-02.md index d42a9e29..0d43dcd0 100644 --- a/docs/java/concurrent/java-concurrent-questions-02.md +++ b/docs/java/concurrent/java-concurrent-questions-02.md @@ -332,6 +332,8 @@ CAS 只对单个共享变量有效,当操作涉及跨多个共享变量时 CAS 不过,在 Java 6 之后, `synchronized` 引入了大量的优化如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销,这些优化让 `synchronized` 锁的效率提升了很多。因此, `synchronized` 还是可以在实际项目中使用的,像 JDK 源码、很多开源框架都大量使用了 `synchronized` 。 +关于偏向锁多补充一点:由于偏向锁增加了 JVM 的复杂性,同时也并没有为所有应用都带来性能提升。因此,在 JDK15 中,偏向锁被默认关闭(仍然可以使用 `-XX:+UseBiasedLocking` 启用偏向锁),在 JDK18 中,偏向锁已经被彻底废弃(无法通过命令行打开)。 + ### 如何使用 synchronized? `synchronized` 关键字的使用方式主要有下面 3 种: diff --git a/docs/java/new-features/java14-15.md b/docs/java/new-features/java14-15.md index f84913e4..34a5f862 100644 --- a/docs/java/new-features/java14-15.md +++ b/docs/java/new-features/java14-15.md @@ -237,7 +237,7 @@ Java 15 并没有对此特性进行调整,继续预览特性,主要用于接 - **Nashorn JavaScript 引擎彻底移除**:Nashorn 从 Java8 开始引入的 JavaScript 引擎,Java9 对 Nashorn 做了些增强,实现了一些 ES6 的新特性。在 Java 11 中就已经被弃用,到了 Java 15 就彻底被删除了。 - **DatagramSocket API 重构** -- **禁用和废弃偏向锁(Biased Locking)**:偏向锁的引入增加了 JVM 的复杂性大于其带来的性能提升。不过,你仍然可以使用 `-XX:+UseBiasedLocking` 启用偏向锁定,但它会提示 这是一个已弃用的 API。 +- **禁用和废弃偏向锁(Biased Locking)**:偏向锁的引入增加了 JVM 的复杂性大于其带来的性能提升。不过,你仍然可以使用 `-XX:+UseBiasedLocking` 启用偏向锁定,但它会提示这是一个已弃用的 API。 - ……