天天看点

为什么SAP不会像JVM那样因为内存溢出heapdump而挂掉

首先说明,这个题目是个伪命题,实际上sap也会out of memory,也会挂。但由于sap管理进程和内存的机制和jvm不同,所以结果不同,不是整个系统挂。对于SAP,我们经常碰到的是“SAP的一个进程死了,需要把它杀掉”,这实际上是sap的一个dialog进程用完了extend memory,进入了priv mode,该进程就像挂了一样,而此时整个SAP系统还是可用的。

所以,为了清晰地解释着个问题,需要对sap的内存管理和进程管理有清晰的理解。

一、内存管理

概览,sap内存区域为虚拟内存,包含公用内存和私用内存。进程有自己的私用内存,公用内存是给所有进程的公共部分使用的。

为什么SAP不会像JVM那样因为内存溢出heapdump而挂掉

1.虚拟内存

虚拟内存 = 分配给SAP的物理内存 + 在硬盘上的操作系统页面文件(基于Windows系统)或 操作系统交换空间(基于Unix或Linux系统)

为什么SAP不会像JVM那样因为内存溢出heapdump而挂掉

更详细的图如下:

为什么SAP不会像JVM那样因为内存溢出heapdump而挂掉

2.私用内存(Local Memory)

私用内存区是给各个独立的工作进程使用过的,包含有为工作进程(Work process)分配的私用内存(local work process memory),以及一旦扩展内存(Extended memory)耗尽后临时分配给工作进程使用的堆内存区(heap memory)

以下两张图是解释local memory及其组成部分local work process memory 和heap memory的作用的。

为什么SAP不会像JVM那样因为内存溢出heapdump而挂掉
为什么SAP不会像JVM那样因为内存溢出heapdump而挂掉

3.公用内存(shared memory)

SAP公用内存可供同一例程(Instance)内的任何进程(包括工作进程,work process)使用。包括 sap buffer、extended memory 、roll buffer 、页面缓存(paging buffer)

四种,存放的东西不同

其中物理内存中的roll buffer 、paging buffer 是和放在硬盘上的SAP roll file 、SAP paging file 相对应的。如果roll buffer不够了,就用roll file ,如果paging buffer不够了,就用paging file

  • sap buffer
为什么SAP不会像JVM那样因为内存溢出heapdump而挂掉
  • 扩展内存(Extended Memory)
为什么SAP不会像JVM那样因为内存溢出heapdump而挂掉
  • roll buffer
为什么SAP不会像JVM那样因为内存溢出heapdump而挂掉
  • 页面缓存(paging buffer)
为什么SAP不会像JVM那样因为内存溢出heapdump而挂掉

4.内存结论

SAP虚拟内存由物理内存和硬盘文件系统组成,分成私用内存和公用内存

私用内存区是给各个独立的工作进程使用过的,包含有为工作进程(Work process)分配的私用内存(local work process memory),以及一旦扩展内存(Extended memory)耗尽后临时分配给工作进程使用的堆内存区(heap memory)

公用内存可供同一例程(Instance)内的任何进程(包括Work process)使用。包括 sap buffer、extended memory 、roll buffer 、页面缓存(paging buffer)四种

其中物理内存中的roll buffer 、paging buffer 是和放在硬盘上的SAP roll file 、SAP paging file 相对应的。如果roll buffer不够了,就用roll file ,如果paging buffer不够了,就用paging file

下面来介绍一下sap的进程是怎么使用虚拟内存的

二、进程管理和用户Transaction

Sap 进程分为DVEBMGS这几种

D = Dialog, V = Update, E = Enqueue, B = Background, M = Message, G = Gateway, S = Spool;

执行事务代码RZ10可以调整工作进程的数量(还可以设白天和晚上两种工作状态) ,例如:                        

rdisp/wp_no_dia = 7

rdisp/wp_no_vb = 2

rdisp/wp_no_vb2 = 1

rdisp/wp_no_enq = 1

rdisp/wp_no_btc  = 3

rdisp/wp_no_spo = 1

所有的前台操作都是由一批有限数量的Dialog进程进行服务的,所以一个Dialog进程可能需要同时服务多个前台进程

一个Dialog进程是如何为多个前台会话服务的?

  • 每一个前台操作,是由一系列Transaction Step组成
  • 每个Transaction Step是SAP ABAP程序独立运行的最小单位
  • 每个Transaction Step作为一个Dialog运行请求被提交给Dispatcher
  • Dispatcher将任务指派给某个Dialog进程去处理

所以,Dialog进程需要在处理每个Transaction Step前后切换用户上下文数据User Context

如下面两张图所示

为什么SAP不会像JVM那样因为内存溢出heapdump而挂掉
为什么SAP不会像JVM那样因为内存溢出heapdump而挂掉

三、Dialog进程与内存的关系 

为什么SAP不会像JVM那样因为内存溢出heapdump而挂掉

上图是一个dialog进程使用内存的过程

  1. 私用内存local work process memory 中的local  roll area会为用户上下文数据User Context提供初始的100到250K(取决于操作系统)内存。这块内存取决于系统参数ztta/roll_first;
  2. 如果local roll area里的内存不足于供用户上下文数据使用,这些数据就会使用公用内存中的SAP扩展内存Extended memory。上下文数据在扩展内存中可用的量取决于ztta/roll_extension设定的最大使用配额;当然不能超过em/initial_size_MB中的值,也就是所有扩展内存的分配值;  
  3. 如果用户上下文所需的内存仍不够的话,它就会根据参数ztta/roll_area从私用内存local work process memory 中的local  roll area里使用剩余的内存块 ;
  4. 如果还不够的话,就会用到私有内存中的堆内存heap memory,可用的内存取决于参数abap/heap_area_dia,(当然abap/heap_area_dia值不能超过abap/heap_area_total),这样就会进入臭名昭著的PRIV状态。如果该进程能完成当前工作,该进程占用的heap memory被释放,该进程就会退出priv状态,恢复正常。
  5. 而如果有多个工作进程(超过rdisp/wppriv_max_no限定的数额时)同时处于这个状态的话,这个heap memory区会被占满,而且dispatch分配器没有足够的dialog 工作进程分配作业(transaction step),这套SAP系统就逐渐进入瘫痪状态。

总结:与J2EE的区别

搞清楚了用户transaction、dialog进程、sap内存管理之间的关系,就明白了sap在机制上相当于多线程,用户的一个完整的操作并不是由固定的一个进程来完成的。也就是说某一个进程因它的私有内存满了而挂了,只影响当时在该进程上操作的某个用户的某个Transaction,但不影响其他用户的transaction选择其他dialog进程来正常执行。

这就是sap系统能支持大量用户事务而不会轻易挂掉的根本原因。