我有很多有ZoneId tz个场的物体. tz字段的所有实例都是通过ZoneId.of静态方法创建的. 我最初 Select ZoneId,而不是普通的String,是希望缓存ZoneId个实例(因为存在有限的时区).然而,在分析了堆之后,我发现这不是真的:

enter image description here

每次使用相同的参数调用ZoneId.of都会创建ZoneRegion的新实例:

ZoneId zoneId1 = ZoneId.of("Europe/Kiev"); //allocates new ZoneRegion
ZoneId zoneId2 = ZoneId.of("Europe/Kiev"); //allocates new ZoneRegion

我的问题是-这是意料之中的,还是这是某种JVM错误?

openjdk version "21.0.1" 2023-10-17
OpenJDK Runtime Environment (build 21.0.1+12-Ubuntu-222.04)
OpenJDK 64-Bit Server VM (build 21.0.1+12-Ubuntu-222.04, mixed mode, sharing)

推荐答案

我的问题是-这是意料之中的,还是这是某种JVM错误?

判断最新的javadoc(JDK 22u),"这些值是单例"没有提到.因为我们可以更简单地陈述你的情况,而不会把堆问题带进go :

// bug claim:
ZoneId a = ZoneId.of("Europe/Kiev");
ZoneId b = ZoneId.of("Europe/Kiev");
System.out.println(a == b); // should print true!

...但这会打印false,因此这意味着支持ZoneId.of do not的机制会导致单例ZoneId对象--要么JDK不存在预缓存的每个可能的ZoneID对象,要么ZoneId.of本身无法建立缓存.

或者这是某种JVM错误?

Java Lang Spec和Java Virtual Machine Spec不会(或不应该)提及这方面的任何内容,因为它不在java.lang包或子包中,对于语言本身至关重要的任何类型都需要在JLS/JVMS中提及.

因此,javadoc是该规范的规范来源.

一百零二

作为参考,current JDK22u sources of ZoneId.

有一句话是这样的:

 * The ID is unique within the system.

关于ZoneID本身,might解释为:"ID"这里是"An Instance of ZoneID"的缩写,但这并不是对这一行的明显解释;他们谈论的是,例如,Europe/Kiev作为一个概念不能同时导致对其所指时区的两种不同概念.文档的这一部分不是关于实现细节级别的概念...并且该系统将缓存该概念,以便不需要存在两个实例.

does包含一个附加条款,即实例将被视为ValueBased(在主javadoc的末尾):您不应该以任何方式假设例如==会做什么(换句话说,他们明确保留引入某种缓存机制的权利,或者这些将成为直接的valhalla风格的值类,首先不具有标识).但这只是简单地规定你不应该依赖either:你不能依赖于重复调用ZoneId.of("Europe/Kiev")返回不同的对象,你可以依赖于这样的调用返回相同的对象.在代码方面,您根本不应该考虑对象的ZoneId实例.

的溶液

如果您的分析器报告强烈建议减少ZoneID实例的数量将有所帮助,那么API文档将授予您缓存这些实例的权限:

private static final Map<String, ZoneId> CACHED_ZONE_IDS = new HashMap<>();

public static ZoneId cachedOf(String id) {
  return CACHED_ZONE_IDS.computeIfAbsent(id, ZoneId::of);
}

如果您担心需要从缓存的 map 中‘超时’不再使用的ZoneIds,您可以查看番石榴的CacheBuilder,但在这里这似乎有点过头了;我将其保留为上面的3行代码.

Java相关问答推荐

Mongo DB Bson和Java:在子文档中添加和返回仅存在于父文档中的字段?

将具有多个未知字段的SON映射到Java POJO

更新我们的一个文物后出现了严重的符号引用错误

H2弹簧靴试验跌落台

工件部署期间出错[Tomcat 8.5.45]

有没有一种方法使保持活动设置专用于java.net.http.HttpClient的一个实例

解析Javadoc时链接的全限定类名

流迭代列表<;对象>;上的NoSuchElementException

为什么JAVA&S清洁器使用链表而不是并发HashSet?

Chunk(Int)已弃用并标记为要删除

用OSQL创建索引

如何在antlr4中跳过所有反斜杠-换行符而保留换行符?

在执行流和相关操作时,使用Java泛型为2个方法执行相同的操作,但对象不同

为什么Collectors.toList()不能保证易变性

如何以编程方式保存workBench.xmi?

如何在Java springboot中从一个端点发送多个时间响应?

IntelliJ IDEA依赖项工具窗口丢失

为什么使用lo索引来解决二进制搜索问题不同于使用hi索引?

将@Transactional添加到Spring框架中链下的每个方法会产生什么效果?

ExecutorService:如果我向Executor提交了太多任务,会发生什么?