使用OpenJ9的类共享功能来减少不同应用程序的单个实例的内存使用量是否可能/合理?
更多详细信息:
该功能似乎是为了在同一台机器上运行同一应用程序的多个实例(例如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
对同一(或类似(应用程序的多个实例使用相同的共享缓存是最佳做法。如果在不同的应用程序之间共享相同的缓存,则可能无法节省(大部分(内存,因为共享缓存包含当前应用程序不需要的其他应用程序存储的类。
OpenJ9正在对类路径上的jar进行时间戳检查。它确保类路径上的类在存储到缓存后没有更新,这样我们就可以安全地将缓存的类返回到类加载器。一旦找到更新,原始缓存类就会被标记为过时。
使用子选项";bootClassesOnly;仅为引导程序类打开类共享。没有人更新引导程序类路径上的内容,所以您不会看到过时的类。
我看到缓存统计信息中有数千个类路径。这些类路径上的内容是更新的还是在运行时生成的?您可以使用-Xshareclasses子选项";printStats=classpath";以显示所有类路径。如果你确定类在运行之间没有更新,你可以使用-Xshareclasses子选项"noTimestampChecks";以关闭时间戳检查。