0

使用 OpenJ9 的类共享功能来减少不同应用程序的单个实例的内存使用是否可能/合理?

更多细节:

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

我想要实现的是,巧合地在同一个 Kubernetes 节点上启动的应用程序使用相同的缓存。由于应用程序使用几乎相同的库,因此应该有大量可以共享的数据。但是,我所经历的是缓存具有很高比例的陈旧类,即使我使用 1GB 的软限制和硬限制,缓存也会变得 100% 满。

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

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
4

1 回答 1

1

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

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

使用子选项“bootClassesOnly”仅为引导类打开类共享。没有人在引导类路径上更新东西,所以你看不到陈旧的类。

我看到缓存统计中有数千个类路径。这些类路径上的东西是更新了还是在运行时生成的?您可以使用 -Xshareclasses 子选项“printStats=classpath”来显示所有类路径。如果您确定类在运行之间没有更新,您可以使用 -Xshareclasses 子选项“noTimestampChecks”来关闭时间戳检查。

于 2020-09-08T16:18:29.337 回答