OpenJ9 class 不同应用程序之间的共享

OpenJ9 class sharing between different applications

是否possible/reasonable利用OpenJ9的class sharing特性来减少不同应用的单个实例的内存占用?

更多详情:

似乎该功能旨在减少 运行在同一台机器(例如 Kubernetes 节点)上连接同一应用程序的多个实例时的内存使用量。对吗?

我想实现的是,碰巧在同一个 Kubernetes 节点上启动的应用程序使用相同的缓存。由于应用程序使用几乎相同的库,因此应该可以共享大量数据。但是,我遇到的情况是缓存的陈旧率很高类,甚至缓存变得 100% 满,即使我使用 1GB 的软硬限制。

具体来说,我已经尝试在同一个 Kubernetes 节点上使用 java -Xshareclasses:cacheDir=/openj9cache,groupAccess,name=somename,nonfatal,persistent,verbose -XX:SharedCacheHardLimit=1g -Xscmx1g <APP> 进行不同的部署。根据我 运行 的应用程序,我看到缓存统计信息如下:

cache layer                          = 0
cache size                           = 1073741216
softmx bytes                         = 1073741824
free bytes                           = 0
Reserved space for AOT bytes         = -1
Maximum space for AOT bytes          = -1
Reserved space for JIT data bytes    = -1
Maximum space for JIT data bytes     = -1
Metadata bytes                       = 937848376
Metadata % used                      = 87%
Class debug area size                = 85868544
Class debug area used bytes          = 4246022
Class debug area % used              = 4%

ROMClass bytes                       = 36481772
AOT bytes                            = 12671632
JIT data bytes                       = 506596
Zip cache bytes                      = 0
Startup hint bytes                   = 360
Data bytes                           = 363936

# ROMClasses                         = 45685
# AOT Methods                        = 2997
# Classpaths                         = 30076
# URLs                               = 0
# Tokens                             = 0
# Zip caches                         = 0
# Startup hints                      = 3
# Stale classes                      = 40496
% Stale classes                      = 88%


Cache is 100% soft full
cache layer                          = 0
cache size                           = 1073741216
softmx bytes                         = 1073741824
free bytes                           = 0
Reserved space for AOT bytes         = -1
Maximum space for AOT bytes          = -1
Reserved space for JIT data bytes    = -1
Maximum space for JIT data bytes     = -1
Metadata bytes                       = 935010252
Metadata % used                      = 87%
Class debug area size                = 85868544
Class debug area used bytes          = 4745600
Class debug area % used              = 5%

ROMClass bytes                       = 40151980
AOT bytes                            = 11919936
JIT data bytes                       = 426448
Zip cache bytes                      = 0
Startup hint bytes                   = 120
Data bytes                           = 363936

# ROMClasses                         = 38554
# AOT Methods                        = 2950
# Classpaths                         = 22680
# URLs                               = 0
# Tokens                             = 0
# Zip caches                         = 0
# Startup hints                      = 1
# Stale classes                      = 6354
% Stale classes                      = 16%


Cache is 100% soft full
base address                         = 0x00007F3D8C059000
end address                          = 0x00007F3DCC000000
allocation pointer                   = 0x00007F3D8F10BB80

cache layer                          = 0
cache size                           = 1073741216
softmx bytes                         = 1073741824
free bytes                           = 706740256
Reserved space for AOT bytes         = -1
Maximum space for AOT bytes          = -1
Reserved space for JIT data bytes    = -1
Maximum space for JIT data bytes     = -1
Metadata bytes                       = 199367772
Metadata % used                      = 54%
Class debug area size                = 85868544
Class debug area used bytes          = 6499570
Class debug area % used              = 7%

ROMClass bytes                       = 51063680
AOT bytes                            = 29461056
JIT data bytes                       = 875612
Zip cache bytes                      = 0
Startup hint bytes                   = 360
Data bytes                           = 363936

# ROMClasses                         = 30778
# AOT Methods                        = 6624
# Classpaths                         = 8349
# URLs                               = 0
# Tokens                             = 0
# Zip caches                         = 0
# Startup hints                      = 3
# Stale classes                      = 3274
% Stale classes                      = 10%


Cache is 34% soft full

最佳做法是为相同(或相似)应用程序的多个实例使用相同的共享缓存。如果您在不同的应用程序之间共享相同的缓存,您可能无法获得(最多)内存节省,因为共享缓存包含 class 由当前应用程序不需要的其他应用程序存储的元素。

OpenJ9 正在对 class 路径上的 jar 进行时间戳检查。它确保 class 路径上的 class 自从存储到缓存中后就没有被更新,这样我们就可以安全地 return 将缓存的 class 加载到 class 加载程序.一旦找到更新,原始缓存 class 将被标记为过时。

使用 sub-option“bootClassesOnly”打开 class 仅 bootstrap class 共享。没有人在 bootstrap class 路径上更新内容,因此您看不到任何陈旧的 classes.

我看到缓存统计信息中有数千条 class 条路径。这些 class 路径上的东西是否得到更新或者它们是在运行时生成的?您可以使用 -Xshareclasses sub-option "printStats=classpath" 来显示所有 class 路径。如果您确定 classes 在运行之间没有更新,您可以使用 -Xshareclasses sub-option "noTimestampChecks" 关闭时间戳检查。