mirror of
https://github.com/Snailclimb/JavaGuide
synced 2025-06-16 18:10:13 +08:00
[docs update]typo
This commit is contained in:
parent
91c491d608
commit
9e476c1af1
@ -71,7 +71,7 @@ FTP 是基于客户—服务器(C/S)模型而设计的,在客户端与 FTP
|
||||
>
|
||||
> 这种将命令和数据分开传送的思想大大提高了 FTP 的效率。
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
## Telnet:远程登陆协议
|
||||
@ -84,4 +84,4 @@ FTP 是基于客户—服务器(C/S)模型而设计的,在客户端与 FTP
|
||||
|
||||
**Telnet 和 SSH 之间的主要区别在于 SSH 协议会对传输的数据进行加密保证数据安全性。**
|
||||
|
||||

|
||||

|
@ -7,7 +7,7 @@ tag:
|
||||
|
||||
HTTP 状态码用于描述 HTTP 请求的结果,比如2xx 就代表请求被成功处理。
|
||||
|
||||

|
||||

|
||||
|
||||
### 1xx Informational(信息性状态码)
|
||||
|
||||
|
@ -51,7 +51,7 @@ OSI 七层模型虽然失败了,但是却提供了很多不错的理论基础
|
||||
|
||||
**应用层位于传输层之上,主要提供两个终端设备上的应用程序之间信息交换的服务,它定义了信息交换的格式,消息会交给下一层传输层来传输。** 我们把应用层交互的数据单元称为报文。
|
||||
|
||||

|
||||

|
||||
|
||||
应用层协议定义了网络通信规则,对于不同的网络应用需要不同的应用层协议。在互联网中应用层协议很多,如支持 Web 应用的 HTTP 协议,支持电子邮件的 SMTP 协议等等。
|
||||
|
||||
|
@ -130,7 +130,7 @@ tag:
|
||||
|
||||
HTTP 状态码用于描述 HTTP 请求的结果,比如2xx 就代表请求被成功处理。
|
||||
|
||||

|
||||

|
||||
|
||||
关于 HTTP 状态码更详细的总结,可以看我写的这篇文章:[HTTP 常见状态码总结(应用层)](./http-status-codes.md)。
|
||||
|
||||
@ -162,8 +162,6 @@ HTTP 是一种不保存状态,即无状态(stateless)协议。也就是说
|
||||
|
||||
最常用的就是利用 URL 重写把 Session ID 直接附加在 URL 路径的后面。
|
||||
|
||||

|
||||
|
||||
### URI 和 URL 的区别是什么?
|
||||
|
||||
* URI(Uniform Resource Identifier) 是统一资源标志符,可以唯一标识一个资源。
|
||||
|
@ -489,8 +489,10 @@ save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生
|
||||
|
||||
Redis 提供了两个命令来生成 RDB 快照文件:
|
||||
|
||||
- `save` : 主线程执行,会阻塞主线程;
|
||||
- `bgsave` : 子线程执行,不会阻塞主线程,默认选项。
|
||||
- `save` : 同步保存操作,会阻塞 Redis 主线程;
|
||||
- `bgsave` : fork 出一个子进程,子进程执行,不会阻塞 Redis 主线程,默认选项。
|
||||
|
||||
> 这里说 Redis 主线程而不是主进程的主要是因为 Redis 启动之后主要是通过单线程的方式完成主要的工作。如果你想将其描述为 Redis 主进程,也没毛病。
|
||||
|
||||
### 什么是 AOF 持久化?
|
||||
|
||||
|
@ -324,7 +324,21 @@ public ScheduledThreadPoolExecutor(int corePoolSize) {
|
||||
- **`ThreadPoolExecutor.DiscardPolicy`:** 不处理新任务,直接丢弃掉。
|
||||
- **`ThreadPoolExecutor.DiscardOldestPolicy`:** 此策略将丢弃最早的未处理的任务请求。
|
||||
|
||||
举个例子: Spring 通过 `ThreadPoolTaskExecutor` 或者我们直接通过 `ThreadPoolExecutor` 的构造函数创建线程池的时候,当我们不指定 `RejectedExecutionHandler` 饱和策略的话来配置线程池的时候默认使用的是 `ThreadPoolExecutor.AbortPolicy`。在默认情况下,`ThreadPoolExecutor` 将抛出 `RejectedExecutionException` 来拒绝新来的任务 ,这代表你将丢失对这个任务的处理。 对于可伸缩的应用程序,建议使用 `ThreadPoolExecutor.CallerRunsPolicy`。当最大池被填满时,此策略为我们提供可伸缩队列。(这个直接查看 `ThreadPoolExecutor` 的构造函数源码就可以看出,比较简单的原因,这里就不贴代码了)
|
||||
举个例子:Spring 通过 `ThreadPoolTaskExecutor` 或者我们直接通过 `ThreadPoolExecutor` 的构造函数创建线程池的时候,当我们不指定 `RejectedExecutionHandler` 饱和策略来配置线程池的时候,默认使用的是 `AbortPolicy`。在这种饱和策略下,如果队列满了,`ThreadPoolExecutor` 将抛出 `RejectedExecutionException` 异常来拒绝新来的任务 ,这代表你将丢失对这个任务的处理。如果不想丢弃任务的话,可以使用`CallerRunsPolicy`。`CallerRunsPolicy` 和其他的几个策略不同,它既不会抛弃任务,也不会抛出异常,而是将任务回退给调用者,使用调用者的线程来执行任务
|
||||
|
||||
```java
|
||||
public static class CallerRunsPolicy implements RejectedExecutionHandler {
|
||||
|
||||
public CallerRunsPolicy() { }
|
||||
|
||||
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
|
||||
if (!e.isShutdown()) {
|
||||
// 直接主线程执行,而不是线程池中的线程执行
|
||||
r.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 线程池常用的阻塞队列有哪些?
|
||||
|
||||
|
@ -95,10 +95,38 @@ JDK 1.8 之前永久代还没被彻底移除的时候通常通过下面这些参
|
||||
下面是一些常用参数:
|
||||
|
||||
```bash
|
||||
-XX:MetaspaceSize=N #设置 Metaspace 的初始(和最小大小)
|
||||
-XX:MaxMetaspaceSize=N #设置 Metaspace 的最大大小,如果不指定大小的话,随着更多类的创建,虚拟机会耗尽所有可用的系统内存。
|
||||
-XX:MetaspaceSize=N #设置 Metaspace 的初始大小(是一个常见的误区,后面会解释)
|
||||
-XX:MaxMetaspaceSize=N #设置 Metaspace 的最大大小
|
||||
```
|
||||
|
||||
**🐛 修正(参见: [issue#1947](https://github.com/Snailclimb/JavaGuide/issues/1947))**:
|
||||
|
||||
1、Metaspace 的初始容量并不是 `-XX:MetaspaceSize` 设置,无论 `-XX:MetaspaceSize` 配置什么值,对于 64 位 JVM 来说,Metaspace 的初始容量都是 21807104(约 20.8m)。
|
||||
|
||||
可以参考 Oracle 官方文档 [Other Considerations](https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/considerations.html) 中提到的:
|
||||
|
||||
> Specify a higher value for the option MetaspaceSize to avoid early garbage collections induced for class metadata. The amount of class metadata allocated for an application is application-dependent and general guidelines do not exist for the selection of MetaspaceSize. The default size of MetaspaceSize is platform-dependent and ranges from 12 MB to about 20 MB.
|
||||
>
|
||||
> MetaspaceSize 的默认大小取决于平台,范围从 12 MB 到大约 20 MB。
|
||||
|
||||
另外,还可以看一下这个试验:[JVM 参数 MetaspaceSize 的误解](https://mp.weixin.qq.com/s/jqfppqqd98DfAJHZhFbmxA)。
|
||||
|
||||
2、Metaspace 由于使用不断扩容到`-XX:MetaspaceSize`参数指定的量,就会发生 FGC,且之后每次 Metaspace 扩容都会发生 Full GC。
|
||||
|
||||
也就是说,MetaspaceSize 表示 Metaspace 使用过程中触发 Full GC 的阈值,只对触发起作用。
|
||||
|
||||
垃圾搜集器内部是根据变量 `_capacity_until_GC`来判断 Metaspace 区域是否达到阈值的,初始化代码如下所示:
|
||||
|
||||
```c
|
||||
void MetaspaceGC::initialize() {
|
||||
// Set the high-water mark to MaxMetapaceSize during VM initializaton since
|
||||
// we can't do a GC during initialization.
|
||||
_capacity_until_GC = MaxMetaspaceSize;
|
||||
}
|
||||
```
|
||||
|
||||
相关阅读: [issue 更正:MaxMetaspaceSize如果不指定大小的话,不会耗尽内存 #1204 ](https://github.com/Snailclimb/JavaGuide/issues/1204) 。
|
||||
|
||||
## 3.垃圾收集相关
|
||||
|
||||
### 3.1.垃圾回收器
|
||||
|
@ -187,7 +187,7 @@ Spring 中 `JdbcTemplate`、`HibernateTemplate` 等以 Template 结尾的对数
|
||||
|
||||
## 观察者模式
|
||||
|
||||
观察者模式是一种对象行为型模式。它表示的是一种对象与对象之间具有依赖关系,当一个对象发生改变的时候,这个对象所依赖的对象也会做出反应。Spring 事件驱动模型就是观察者模式很经典的一个应用。Spring 事件驱动模型非常有用,在很多场景都可以解耦我们的代码。比如我们每次添加商品的时候都需要重新更新商品索引,这个时候就可以利用观察者模式来解决这个问题。
|
||||
观察者模式是一种对象行为型模式。它表示的是一种对象与对象之间具有依赖关系,当一个对象发生改变的时候,依赖这个对象的所有对象也会做出反应。Spring 事件驱动模型就是观察者模式很经典的一个应用。Spring 事件驱动模型非常有用,在很多场景都可以解耦我们的代码。比如我们每次添加商品的时候都需要重新更新商品索引,这个时候就可以利用观察者模式来解决这个问题。
|
||||
|
||||
### Spring 事件驱动模型中的三种角色
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user