At the very begining when I started to develop in ABAP I was wondering why I cannot clear all global data at once after I do all my calculations? As this is something that it's very useful when you create a report which just show some figures and you don't need anymore all the internal tables or objects that you used to prepare output table. So to free memory then just before calling ALV I was always refreshing all tables and clearing work areas, but this was something that had to be done manually so I was a little bit angry that I cannot automize it... and then I started to look for the way how to automize it.
I knew that SE80 is displaying all globals but I couldn't find how it's done there. As you may know debuggin the code which was done by SAP is creepy usually and after spending some hours on that I gave up. But it returned someday I just simply saw FM 'RS_PROGRAM_INDEX' and that was enough to create fast a method to free all global data for me.
So let's start with definition. We will need a range type which we will use to call the method with objects to be excluded from clearing (like ALV output table or ALV objects)
types: tt_ra_scompo_name type range of scompo-name .
types: t_scompo_name type line of tt_ra_scompo_name . type-pools abap .
constants cname_cl_gui_custom_container type abap_abstypename value '\CLASS=CL_GUI_CUSTOM_CONTAINER'.
constants cname_cl_gui_textedit type abap_abstypename value '\CLASS=CL_GUI_TEXTEDIT'.
constants cname_cl_gui_alv_grid type abap_abstypename value '\CLASS=CL_GUI_ALV_GRID'.
Method definision is simple, just the table with exluded objects and program name.
class-methods free_global_data
importing
!it_exclude type tt_ra_scompo_name optional
!i_program type syst-repid
preferred parameter it_exclude .
Implementation of the method:
method free_global_data.
field-symbols: <any> type any,
<comp> type scompo,
<token> type stoken,
<ccont> type ref to cl_gui_custom_container,
<textedit> type ref to cl_gui_textedit,
<alvgrid> type ref to cl_gui_alv_grid.
types: type_tokens type table of stoken ,
type_statements type table of sstmnt,
type_levels type table of slevel.
data: m_k(30) value 'CONSTANTS'.
data: mt_src type table of string,
mt_tokens type type_tokens ,
mt_statements type type_statements ,
mt_keywords like table of m_k,
mt_levels type type_levels ,
m_overflow(4096).
data: m_lenght type i.
data: m_shift type i.
data: mt_compo type table of scompo.
data: mt_cross_ref type table of cross.
data: mt_inc type table of d010inc.
data: ms_exclude like line of it_exclude.
data: mt_exclude type tt_ra_scompo_name.
data: m_compname(255) type c.
data: m_classref type ref to cl_abap_typedescr.
data: m_classname type abap_abstypename.
"selecting global data names
call function 'RS_PROGRAM_INDEX'
exporting
pg_name = i_program
* WITHOUT_TREE = ' '
* IMPORTING
* MESSAGE_CLASS = MESSAGE_CLASS
tables
compo = mt_compo
cross_ref = mt_cross_ref
inc = mt_inc
exceptions
syntax_error = 1
others = 2.
check sy-subrc eq 0.
"selecting constants to avoid dump
append m_k to mt_keywords.
read report i_program into mt_src.
scan abap-source mt_src
tokens into mt_tokens
statements into mt_statements
keywords from mt_keywords
levels into mt_levels
with includes
with list tokenization
preserving identifier escaping
frame program from i_program.
sort mt_tokens by str ascending.
"let's find all variables with length definition like var(5) type c
"and shift it's name to var
loop at mt_tokens assigning <token> where str ca '()'.
find '(' in <token>-str.
<token>-str = <token>-str+0(sy-fdpos).
endloop.
"if we do not want to exclude any global data then the range is empty,
"if we let it like this then we will not clear anything
if it_exclude[] is initial.
clear ms_exclude.
ms_exclude-sign = 'I'.
ms_exclude-option = 'EQ'.
ms_exclude-low = 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'.
append ms_exclude to mt_exclude.
else.
mt_exclude[] = it_exclude[].
endif.
"we ommit field symbols as they will be cleared when source data
"will be cleared.
loop at mt_compo assigning <comp> where name not in mt_exclude[]
and type eq 'D'
and name na '<>'.
read table mt_tokens with key str = <comp>-name
transporting no fields binary search.
if sy-subrc ne 0.
unassign <any>.
clear m_compname.
concatenate '(' i_program ')' <comp>-name into m_compname.
assign (m_compname) to <any>.
if <any> is assigned and sy-subrc eq 0.
m_classref ?= cl_abap_classdescr=>describe_by_data( <any> ).
if sy-subrc eq 0 and m_classref->kind eq 'R'.
m_classname = cl_abap_classdescr=>get_class_name( <any> ).
case m_classname.
when cname_cl_gui_custom_container.
assign <any> to <ccont>.
if <ccont> is not initial.
<ccont>->free(
exceptions
cntl_error = 1
cntl_system_error = 2
others = 3
).
if sy-subrc <> 0.
*
endif.
endif.
when cname_cl_gui_alv_grid.
assign <any> to <alvgrid>.
<alvgrid>->free(
exceptions
cntl_error = 1
cntl_system_error = 2
others = 3
).
if sy-subrc <> 0.
*
endif.
when cname_cl_gui_textedit.
assign <any> to <textedit>.
<textedit>->free(
exceptions
cntl_error = 1
cntl_system_error = 2
others = 3
).
if sy-subrc <> 0.
*
endif.
endcase.
endif.
free: m_classname, m_classref.
free <any>. clear <any>.
endif.
"now try free table, as the one with header line will not
"be cleared by previous assigment.
unassign <any>.
clear m_compname.
concatenate '(' i_program ')' <comp>-name '[]' into m_compname.
assign (m_compname) to <any>.
if <any> is assigned and sy-subrc eq 0.
free <any>.clear <any>.
endif.
endif.
endloop.
endmethod.
Example of use: (we can use * in names for faster exclusion)
data: fr_exclude type zcl_abapblog_com=>tt_ra_scompo_name.
data: fs_exclude like line of fr_exclude.
fs_exclude-sign = 'I'.
fs_exclude-option = 'EQ'.
fs_exclude-low = 'GT_PARAMS'.
append fs_exclude to fr_exclude.
fs_exclude-option = 'CP'.
fs_exclude-low = 'G_DYNPRO_*'.
append fs_exclude to fr_exclude.
fs_exclude-option = 'CP'.
fs_exclude-low = 'G_DYN_*'.
append fs_exclude to fr_exclude.
zcl_abapblog_com=>free_global_data(
it_exclude = fr_exclude
i_program = sy-repid ).
Enjoy the code :)