Recent question on SCN about the ABAP memory allocation, inspired me to do some reading and research on how memory is allocated for variables in ABAP programs.
You can read the question at Memory Analysis. You should read the problem before moving further.
At high level problem: Memory allocation is different for same variables with same components, but declared differently. Indeed there is a difference of few bytes in some cases, but not in all cases.
So, I started doing some reading and some debugging. From online help Memory Requirements for Deep Data Objects, I found this:
The memory requirement for the reference is 8 byte. With data and object references, this is the memory requirement of the explicitly declared reference variable. With strings, internal tables, and boxed components, an implicit reference is created internally. As long as no dynamic memory is requested, the memory requirement for a string, internal table, or boxed component is exactly 8 bytes.
Series of different tests
I performed the series of various tests using the following program. I modified the code to include local type instead of standard types to play with them. Check that in various tests.
types: BEGIN OF lty_COMT_TEXT_TEXTDATA, STXH TYPE STXH, LINES TYPE COMT_TEXT_LINES_T, FUNCTION TYPE TDFUNCTION, end of lty_comt_text_textdata. types: BEGIN OF ztest_src, ref_kind type c LENGTH 5. include type LTY_COMT_TEXT_TEXTDATA. types: end of ztest_src. types: BEGIN OF ztest_trt, REF_KIND TYPE c LENGTH 5, STXH TYPE STXH, LINES TYPE COMT_TEXT_LINES_T, FUNCTION TYPE TDFUNCTION, end of ztest_trt. DATA: TRT TYPE ZTEST_TRT, SRC TYPE ZTEST_SRC, LO TYPE REF TO CL_ABAP_TYPEDESCR, LSRC TYPE REF TO CL_ABAP_TYPEDESCR, LTRT TYPE REF TO CL_ABAP_TYPEDESCR. DATA: REF_KIND TYPE CHAR80, STXH TYPE STXH, LINES TYPE COMT_TEXT_LINES_T, FUNCTION TYPE TDFUNCTION. CALL METHOD CL_ABAP_TYPEDESCR=>DESCRIBE_BY_DATA EXPORTING P_DATA = src RECEIVING P_DESCR_REF = LSRC. CALL METHOD CL_ABAP_TYPEDESCR=>DESCRIBE_BY_DATA EXPORTING P_DATA = TRT RECEIVING P_DESCR_REF = LTRT. BREAK-POINT.
Test 1 – Without the table LINES
I removed the table LINES from both of the variables SRC & TRT, the memory allocation is same. Without the LINES table, which is the only itab, both of the variables are flat structure, not the deep structure. The REF_KIND is CHAR1 here.
Test 2 – Without the field REF_KIND
I removed the field REF_KIND from both, the memory allocation is also same.
Test 3 – Without the field FUNCTION
I removed the field FUNCTION, the memory allocation is not same, even though the fields are same. This time the REF_KIND is CHAR1.
Test 4 – Without the structure STXH
I removed the structure STXH, the memory allocation is same for both variables:
Test5 – Field with CHAR1 and Test 6 – Field with CHAR3
I now keep all the fields and start playing with the length of the variable REF_KIND. In both of these tests, the memory allocation is not same for both variables – difference of 8 bytes.
Test 7 – Field with CHAR4
I changed the length of REF_KIND to CHAR4 and the allocation is same for both variables.
Whenever there is memory allocation for deep structures, I think:
SAP allocates the memory the blocks of 8 when the variable is deep structure.
Lets walk through using this and verify the results
Individual memory consumption is:
- REF_KIND – CHAR1 – 2 bytes
- STXH – 746 bytes
- LINES table – 8 bytes
- FUNCTION – 2 bytes
For test 1 (without the table LINES) the allocation is the total of all those bytes 750 = 2 + 746 + 2.
For test 2 (without the REF_KIND) the allocation happened in the blocks. So, total would 746 bytes (STXH) would be 93.25 blocks would be 94 full blocks + 8 bytes (LINES) would be 1 block + 2 bytes (FUNCTION) would be 1 full block, which would be 96 blocks to 768 bytes. Since in this test there is no REF_KIND, there is no bytes for that.
For test 3 (without the FUNCTION), TRT total would be 746 bytes (STXH) + 8 bytes (LINES) + 2 bytes (REF_KIND) = 756 bytes to 94.5 blocks, rounding to 95 blocks or 760 bytes. Whereas SRC total would be 746 bytes (STXH) + 8 bytes (LINES) = 754 bytes or 94.25, rounding to 95 blocks. Add full 1 block for 2 bytes of (REF_KIND), which would be 96 blocks. For SRC, the initial allocation happened for the included type and rounded to next block. After this initial allocation, the rest of the variables would be allocated as separate blocks. We would need extra block for REF_KIND in SRC vs TRT is because the fields LINES and STXH is part of the included type LTY_COMT_TEXT_TEXTDATA.
The logic for test 3 should be applicable to all the lengths of REF_KIND or if there are more variables. Say REF_KIND with CHAR1, CHAR2 and CHAR3 (Test 5,6). But for CHAR4 (Test 7), there is some different calculation. SRC follows well the calculation so doesn’t ask for the next block but TRT asks for the next block. So, the memory allocation for both variable matches. That happens when the REF_KIND is in multiple of 4 say 8, 12, 16 and so on, which would be 8 bytes or 1 block of memory. I think that happens due to the free bytes left in the overall memory. TRT requests new block as soon as it has about only 4 bytes free.
For test 4 (without the STXH), the allocation happens in the blocks for each fields separately. 1 block for 8 bytes (LINES) + 1 block for 2 bytes (FUNCTION) + 1 block for 2 bytes(REF_KIND) would be 3 blocks to 24 bytes. Using the same analysis as above, TRT seems to be asking for 1 more block when total is reached to 4 free bytes ( 16 – 12 (8 bytes+2 bytes+2bytes, respectively for LINES, FUNCTION, REF_KIND)). So, the total for TRT comes to like 3 block or 24 bytes.
We may come to these conclusions at end:
- For Flat structures, the memory is allocated based on the 2 bytes for each character
- For Deep structures, the memory is allocated with blocks where 1 block has 8 bytes
- When there are include types in deep structures, the memory allocation happens from inner most to outer components in blocks
- When there are not more than 4 free bytes left in deep structures, a new block is requested (need to be confirmed!!)
What do you think?
My basis for calculation may be wrong. You are more than welcome to explain me if they are
SCN Discussion: Memory Analysis