如何使用@Contented关键字避免伪缓存行与调优与解决Idea注解报错问题,idea@Contented报错。
1.注解概述
1.1使用范围
Contented注解的Target包含了Field与Type,说明可以在类或字段中@Contented都可以使用注解。当注解在类上时,表明类中所有字段均被统一到一个缓存行,当注解在字段上(group tag不同)时,每个字段独立缓存行
1.2 注解默认值
默认值为group tag,这个值用于在多个字段注解中需要将多个字段放入同一个缓存行的情况。
如:
变量a与变量c具有相同的group tag,变量b与变量d具有相同的group tag,程序执行后,变量a与c将会在同一个缓存行中,bd同理。
2. 运行条件
2.1 包引用限制
在jdk8中,注解在sun.misc包中,在jdk9-14中,此注解找不到了,发现已经变更到了jdk.internal.vm.annotation包中,这是因为在9开始,启用了JPMS(Java Platform Module System),所以无法找到了,在我们使用的过程中,需要使用参数将其加入: --add-exports java.base/jdk.internal.vm.annotation=ALL-UNNAMED
IDEA可以参照如下方式配置,配置完成后,使用注解就不会报错了:
2.2 移除注解限制
@Contented注解默认关闭,在使用注解后,需要在程序参数中加入 -XX:-RestrictContended 参数,用于移除注解限制使之生效。
3. 配置参数
3.1 填充大小配置
@Contented注解的方式也是使用缓存填充来规避这个问题的,目前大多数的缓存行都是64字节或128字节,所以@Contented的默认填充是128字节,这在64字节缓存行的CPU中可能会造成大量的缓存浪费,所以需要使用 -XX:ContendedPaddingWidth 配置来控制缓存行大小,该配置支持0-8192(8k)范围。
3.2 禁用@Contented
在内存比较紧张并对性能要求不高的情况下我们也可以使用参数 -XX:-EnableContended 来禁用@Contented注解(时间换空间)。
因为在2.2中已经表示了默认会禁止,所以这里的禁用在理解上可能会有点冲突。这是因为这个注解是用于禁用所有@Contented,而2.2中是打开外部@Contented注解。因为在内部中,ConCurrentHashMap等很多类都使用到了这个注解,默认是打开的,所以在一定情况下可以禁用此注解。