Poison


  • 首页

  • 归档

  • 标签

  • 搜索
close
Poison

Striped

发表于 2022-03-01

在业务中曾有为不同的 key 的操作实现锁语义的需求,常见的实现为构建一个线程安全的 Map 实现然后为每个 key 创建对应的对象用于互斥锁,但是该实现存在内存泄漏的问题,即随着不同 key 不停地出现,该 Map 实例会越来越大,之前为每个 key 创建的对象一直驻留在内存中,即使 key 永远不再出现。比如 JDK 7 引入的支持并行类加载的特性 Multithreaded Custom Class Loaders in Java SE 7 中,引入了如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// Maps class name to the corresponding lock object when the current
// class loader is parallel capable.
// Note: VM also uses this field to decide if the current class loader
// is parallel capable and the appropriate lock object for class loading.
private final ConcurrentHashMap<String, Object> parallelLockMap;

/**
* Returns the lock object for class loading operations.
* For backward compatibility, the default implementation of this method
* behaves as follows. If this ClassLoader object is registered as
* parallel capable, the method returns a dedicated object associated
* with the specified class name. Otherwise, the method returns this
* ClassLoader object.
*
* @param className
* The name of the to-be-loaded class
*
* @return the lock for class loading operations
*
* @throws NullPointerException
* If registered as parallel capable and {@code className} is null
*
* @see #loadClass(String, boolean)
*
* @since 1.7
*/
protected Object getClassLoadingLock(String className) {
Object lock = this;
if (parallelLockMap != null) {
Object newLock = new Object();
lock = parallelLockMap.putIfAbsent(className, newLock);
if (lock == null) {
lock = newLock;
}
}
return lock;
}
阅读全文 »
Poison

ConcurrentHashMap

发表于 2022-02-20

本文主要记录 JDK 12 中 ConcurrentHashMap 的扩容实现。首先需要关注的为 sizeCtl 变量,其定义如下:

1
2
3
4
5
6
7
8
9
/**
* Table initialization and resizing control. When negative, the
* table is being initialized or resized: -1 for initialization,
* else -(1 + the number of active resizing threads). Otherwise,
* when table is null, holds the initial table size to use upon
* creation, or 0 for default. After initialization, holds the
* next element count value upon which to resize the table.
*/
private transient volatile int sizeCtl;
阅读全文 »
Poison

com.sun.management.OperatingSystemMXBean.getSystemCpuLoad()

发表于 2022-02-18

我们发现在部分实例上采集的 CPU 使用率明显不正确,出问题时采集到的值总是高于实际值,进入实例通过 top 等命令确认 CPU 使用率并不高,且有时重启应用后采集的 CPU 使用率又会正常,再次重启后可能又不正常,其中一台单核 CPU 实例的 CPU 使用率不正常时的 Grafana 监控图表如下图所示:


阅读全文 »
Poison

Cache-Control: max-age

发表于 2022-02-07

一直以为 max-age 设置的值表示本地浏览器接收到响应后从当前时刻开始计算的可存活的时间,今天查了个问题,发现并不是。根据 RFC 中的描述,max-age 表示自源站服务器端生成响应后的最大生存时间,并不是自本地浏览器接收到响应后的最大生存时间。

A response’s age can be calculated in two entirely independent ways:

  1. now minus date_value, if the local clock is reasonably well synchronized to the origin server’s clock. If the result is negative, the result is replaced by zero.
  2. age_value, if all of the caches along the response path implement HTTP/1.1.

Given that we have two independent ways to compute the age of a response when it is received, we can combine these as corrected_received_age = max(now - date_value, age_value) and as long as we have either nearly synchronized clocks or all HTTP/1.1 paths, one gets a reliable (conservative) result.

同时发现对没有设置 Cache-Control 的资源,浏览器对部分资源进行了 If-Modified-Since 探测,而部分资源没有进行探测直接使用了本地缓存,查了下文档,原来是根据资源的 Last-Modified 距当前时间的差值来决定是否缓存一段时间,简单来说就是如果一个资源上次修改的时间已经很久了,那么我们可以认为在一定时间段内,该资源不会被修改,所以这时即使没有设置 Cache-Control,浏览器也会将该资源缓存一段时间。典型的缓存时间计算公式为 (current time - last modified time) / 10。

Reference

RFC 2616 - Hypertext Transfer Protocol – HTTP/1.1 - 13.2.3 Age Calculations
RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching - 4.2.2. Calculating Heuristic Freshness
http - What happens if you don’t set cache-control header? - Webmasters Stack Exchange

Poison

Methods Duplicated in Multiple Proxy Interfaces

发表于 2022-01-21

在之前的项目中,多数据源路由曾采用在接口上使用自定义注解指定数据源的方式实现。直到前几天,有同事反馈使用了自定义注解但是数据源切换没有生效,经过排查后,确认是多接口存在相同方法导致,简化后的部分代码如下,原 DAO 接口定义为:

1
2
3
4
5
public interface BizDao {

List<BizDO> queryPage();

}

而后同事新写了个 DAO 接口并继承了 BizDao,简化后的代码如下:

1
2
3
4
5
6
7
8
@DataSource(Database.ANALYTIC)
public interface BizAnalyticDao extends BizDao {

List<BizDO> queryList();

List<BizDO> queryPage();

}
阅读全文 »
123…23

115 日志
128 标签
GitHub
© 2016 - 2022 Poison 蜀ICP备16000644号
由 Hexo 强力驱动
主题 - NexT.Mist