确定 JVM 服务器的语言环境存储需求
确定实际存储器需求后,可以确定是否需要修改提供的 DFHAXRO 选项。 这允许选择避免需要增量存储器分配的值,或者将该值减少到可接受的级别。
关于此任务
DFHAXRO 中的 HEAP64 运行时选项控制 JVM 服务器的 Language Environment ® 相关可调度单元组的堆大小。 此选项包含 64 位, 31 位和 24 位存储器的设置。 如果需要,您可以使用自己的程序来代替 DFHAXRO。 必须在 JVMSERVER 资源上指定程序。
过程
- 在 DFHAXRO 中设置 RPTO (ON) 和 RPTS (ON) 选项。 这些选项在提供的 DFHAXRO 源中的注释中。 指定这些选项将导致 Language Environment 报告存储选项,并编写显示实际使用的存储器的存储报告。
- 禁用 JVMSERVER
资源。JVM 服务器关闭,并除去 Language Environment 相关可调度单元组。
- 启用 JVMSERVER 资源。 CICS® 使用 DFHAXRO 中的 Language Environment 运行时选项为 JVM 服务器创建封套。 JVM 也会启动。
- 在 JVM 服务器中运行 Java™ 工作负载,以收集有关 Language Environment 相关可调度单元组所使用的存储器的数据。
- 从 DFHAXRO 中除去 RPTO (ON) 和 RPTS (ON) 选项。
- 禁用 JVMSERVER 资源以生成存储报告。 存储器报告包含有关初始 Language Environment 相关可调度单元组堆存储器的建议。 64 位用户堆统计信息中的条目 "建议初始大小" 包含建议值,并且等于 JVM 服务器使用的 Language Environment 相关可调度单元组堆存储总量。
结果
存储报告保存在 z/OS® UNIX 中的 stderr 文件中,或者如果您使用的是 JOBLOG 或 DD:// 路由语法,那么还可以转至 CICS JES 输出。 该目录取决于您是否在 JVM 概要文件中为 JVM 重定向了输出。 如果不存在重定向,那么该文件将保存在 JVM 的工作目录中。 如果未在概要文件中为 WORK_DIR 设置任何值,那么该文件将保存在 /tmp 目录中。
使用存储器报告中的信息为 DFHAXRO HEAP64 选项中的 Language Environment 相关可调度单元组堆存储器选择合适的值。 存储需求可能从一个 CICS 执行更改为下一个执行,对于共享一个 DFHAXRO 的不同 CICS 系统,存储需求通常不相同,因此需要进行折衷。
正常目的是将 HEAP64 初始分配设置为建议的大小,以避免或减少增量数。 使用的增量越多, z/OS 存储器与主动使用的 Language Environment 存储器的比率就越有可能增加。 许多增量还会导致 Language Environment 用于管理 HEAP64 存储请求的 CPU 时间量增加。 Java 7.0 在 Language Environment 64 位 HEAP 存储器中分配 Java 堆,这可能会导致建议进行大型初始分配。 在这种情况下,您应该从建议的大小中减去 -Xmx 值,并使用余数 (应该小于 -Xmx) 作为初始分配。 这将强制 Language Environment 在其自己的内存对象中分配 Java 堆作为 Language Environment HEAP 增量。 以后的 Java 发行版通过 IARV64 而不是通过 Language Environment 存储请求将 JVM 堆分配为内存对象。 如果使用包含 -Xmx的初始分配来执行 Java 迁移,那么它通常会将用于 Java 堆的存储器加倍,并且可能导致 MEMLIMIT 过小。
分配多个增量可能会产生 Storage Leak的影响,这表现为 z/OS 存储器随时间不断增加。 在实践中,这更有可能是 Storage Creep,其特点是 z/OS 已分配存储器和 Language Environment 可用存储器都有所增加。 "存储器泄漏" 显示 z/OS 和 Language Environment 使用的存储器都在持续增加。 31 位 HEAP64 存储器在 z/OS 子池 1 中分配。 在 Java 7.0中, JIT 存储器是在 z/OS 子池 1 中分配的,随着时间的推移,其大小自然会以略高于 2MB 的增量递增。 在以后的 Java 发行版中,将以 2MB 增量在 z/OS 子池 2 中分配 JIT 存储器。
HEAPPOOLS 和 HEAPPOOLS64 在缺省 DFHAXRO 中处于活动状态,并且可以在配置时生效,但正确的值取决于工作负载,因此可能很难进行精确调整。
应检查 STACK64 以确保所使用的最大存储空间不接近定义的限制 (通常为 16 MB)。 超过限制将导致运行时错误。
从 LE RPTSTG 输出中不明显的是,当使用 STACK64(1M,1M,16M) 为 JVM 线程堆栈扩展提供安全值时,可能会导致在 GDSA 扩展期间需要较大的 MEMLIMIT 以避免 CICS SOS 高于 Bar。 对于最大 16M ,将在三个内存对象中为每个 JVM 线程分配 20 MB (16 + 1 MB 之一, 2 MB 之一和 1 MB 之一)。 通常只有 3 MB 可用 (保留 17 MB 作为隐藏存储器) ,这将计入 z/OS IARV64 MEMLIMIT 检查。 但是, CICS 会对所有 20 MB 进行计数,以决定它是否可以在不超过 MEMLIMIT 的情况下将 GDSA 扩展为 GB 的倍数。 对于 CICS MEMLIMIT 检查,单个 JVM 服务器可以合法地使用超过 200 个线程, 200 个线程相当于大约 4 GB。 这不是一个错误。 因此,将 STACK64 最大值减小到仍允许某些扩展的较小值可帮助减小 MEMLIMIT 大小以及 SOS 高于 Bar 的可能性。 建议在生产中使用之前,先在合适的负载测试环境中验证较小的 STACK64 最大值。
示例
HEAPPOOLS(ALIGN,8,10,32,10,128,10,256,10,1024,10,2048,10,0,10,0,10,0,10,0,10,0,10,0,10)
HEAPPOOLS64(ALIGN,8,4000,32,2000,128,700,256,350,1024,100,2048,50,3072,50,4096,50,8192,
25,16384,10,32768,5,65536,5)
HEAP64(256M,4M,KEEP,4194304,1048576,KEEP,1024,1024,KEEP)
LIBHEAP64(3M,3M,FREE,16384,8192,FREE,8192,4096,FREE)
STACK64(1M,1M,16M)
THREADSTACK64(OFF,1M,1M,128M) 以下示例是部分 RPTSTG 输出:STACK64 统计信息: 初始大小: 1M 增量大小: 1M 所有并发线程使用的最大数目: 1M 任何线程使用的最大数量: 1M -不需要更改 分配的增量数: 0 THREADSTACK64 统计信息: 初始大小: 1M 增量大小: 1M 所有并发线程使用的最大数目: 0M 任何线程使用的最大数量: 0M -未使用 分配的增量数: 0 64bit 用户 HEAP 统计信息: 初始大小: 256M 增量大小: 4M 已使用的堆存储总量: 730857472 建议的初始大小: 697M -使用此 成功获取堆请求数: 783546 成功的可用堆请求数: 780785 已分配的段数: 135-增量过多 Number of segments freed: 0 31bit 用户 HEAP 统计信息: 初始大小: 4194304 增量大小: 1048576 已使用的总堆存储器 (建议的初始大小): 137165672-使用此 成功获取堆请求数: 1345332 成功的可用堆请求数: 1345260 分配的段数: 125-增量过多 Number of segments freed: 0 64bit 库 HEAP 统计信息: 初始大小: 3M 增量大小: 3M 已使用的堆存储总量: 4640032 建议的初始大小: 5M 成功获取堆请求数: 113381 成功的可用堆请求数: 112860 已分配的数据段数: 1-低,因此不需要更改 Number of segments freed: 0 31bit 库 HEAP 统计信息: 初始大小: 16384 增量大小: 8192 已使用的堆存储总量 (建议的初始大小): 520 成功获取堆请求数: 33725 成功的可用堆请求数: 33725 已分配的数据段数: 1-低,因此不需要更改 Number of segments freed: 0 当前 CellSizes的建议百分比: HEAPP (ALIGN,8,1,32,1,128,1,256,1,1024,1,2048,1,0)
查看 RPTSTG 输出时,请记住 HEAP64 增量大小适用于 Language Environment 分配的最小存储量,并且任何增量都可能大大大于该值。 因此,无法准确确定在分配了 1 个或更多增量时使用了多少 z/OS 存储器。 对于 64bit HEAP (即 135) ,将报告实际增量数,对于 31bit HEAP ,实际增量数比显示的 (即 124 而不是 125) 少 1。
由于使用增量时 Language Environment 的存储管理的工作方式,因此分配的 31 位和 64 位 z/OS 存储量可能显着高于 RPTSTG "最大已用" 中所显示的存储量。
建议的 DFHAXRO 更改为:
* 堆存储器
DC C'HEAP64(700M, ' Initial 64bit heap-change (Note 1)
DC C'4M, ' 64bit 堆增量
DC C' KEEP , ' 64bit 保留增量
DC C'128M, ' 初始 31bit heap-change (注 2)
DC C'2M, ' 31bit 堆增量-更改 (注 3)
DC C' FREE , ' 31bit 增量已释放-更改 (注 4)
DC C'1K, ' 初始 24bit 堆
DC C'1K, ' 24bit 堆增量
DC "KEEP)" 保留 24bit 增量
* 堆池
DC C'HP64(ALIGN) '
DC C' HEAPP (ALIGN,8,1,32,1,128,1,256,1,1024,1,2048,1,0) ' -更改 (注 5)
* 库堆存储器
DC C'LIBHEAP64(3M,3M) ' 初始 64bit 堆-不更改 (注 6)
* 64bit 堆栈存储器
DC C'STACK64(1M,1M,16M) ' -考虑更改 (注 7)
- 如 RPTSTG output 64bit "建议的初始大小" 加上少量增加所示。
- 如 RPTSTG 输出 31bit "建议的初始大小" 所示,但在我们使用 FREE 时减少了一小部分。
- 31 位 HEAP 增量作为值 2M 可能更好,而不是 1M。
- (可选) 使用 31 位 HEAP FREE 可能会导致分配用于映射 "已使用的总堆存储器" 的 z/OS 存储器少于使用 KEEP 的存储器。
- 如 HEAPPOOLS 统计信息后的 RPTSTG 输出所建议,但可能受益于进一步优化。 缺省值 128MB 的 31 位堆初始大小的 10% 可能会导致分配过多的存储量。 在初始堆大小 128MB 的 10% 中,至少有 6 个池会导致分配 77MB 。 这将包括在 "已使用的堆存储总量" 值中 (因为在该值中分配了 HEAPPOOLS 个存储扩展数据块) ,而不考虑以产品方式使用池 s 的百分比。 使用大于 256 个字节的 HEAPPOOLS 单元大小可能会导致低效地使用 Language Environment HEAP 存储器。
- 仅需要一个增量,这不是问题。
- 使用的最大容量为 1MB。 在检查 CICS 是否可以分配新的 GDSA 扩展数据块时,将 16M 的最大值减少到 8 MB 甚至更低的值将显着减少 CICS 计入 MEMLIMIT 的 STACK64 存储量。 在将 STACK64 更改迁移到生产环境之前,应该对这些更改进行彻底测试。
这是在同一 JVM 服务器的另一次运行上使用 31 位 HEAP FREE 的示例。 "段数" 显示已执行的 GETMAIN和 FREEMAIN的数目,这在 JVM 服务器处于活动状态的时间内较低。 2 的差异显示相关可调度单元组仅在初始分配加一个增量的情况下终止,这可能小于 "堆存储总量" ,并显示 FREE 的有效性。 "已使用的堆存储总量" 较高,但从 JVM 服务器的一次运行到另一次运行的任何总计经常发生更改,因此仅基于一组 RPTSTG 的更改可能无法提供最佳设置。
31bit 用户 HEAP 统计信息: 初始大小: 134217728 增量大小: 2097152 已使用的堆存储总量 (建议的初始大小): 154056664 成功获取堆请求数: 3253239 成功的可用堆请求数: 3253176 分配的段数: 149 释放的段数: 147
It is important to read the Language Environment Debugging Guide in order to correctly interpret RPTSTG output.