How to force-free memory from deleted entries in internal tables in SAP ABAP, since the garbage collector won't touch these. This is only needed in rare occasions and/or when memory fragmentation needs to be avoided.
This method will do it fast, and correctly:
This method will do it fast, and correctly:
CLASS cl_demo DEFINITION.
PUBLIC SECTION.
CLASS-METHODS compact CHANGING ct_tab TYPE ANY TABLE.
ENDCLASS.
CLASS cl_demo IMPLEMENTATION.
METHOD compact.
FIELD-SYMBOLS: <lt_buffer> TYPE ANY TABLE,
<lt_buffer_std> TYPE STANDARD TABLE,
<ls_buffer> TYPE any,
<ls_buffer_prev> TYPE any.
DATA: ltr_buffer TYPE REF TO data,
lsr_buffer TYPE REF TO data,
l_kind TYPE c LENGTH 1.
" simple case:
IF ct_tab IS INITIAL.
FREE ct_tab.
RETURN.
ENDIF.
CREATE DATA ltr_buffer LIKE ct_tab.
DESCRIBE TABLE ct_tab KIND l_kind.
CASE l_kind.
WHEN sydes_kind-standard.
ASSIGN ltr_buffer->* TO <lt_buffer_std>.
<lt_buffer_std> = ct_tab.
" this will create/copy a new instance of the table
APPEND INITIAL LINE TO <lt_buffer_std>.
DELETE <lt_buffer_std> INDEX sy-tabix.
ct_tab = <lt_buffer_std>.
WHEN OTHERS. " hased / sorted (unique/non-unique)
ASSIGN ltr_buffer->* TO <lt_buffer>.
<lt_buffer> = ct_tab.
LOOP AT <lt_buffer> ASSIGNING <ls_buffer>.
" this is done only once: work with a actual line copy
CREATE DATA lsr_buffer LIKE LINE OF ct_tab.
ASSIGN lsr_buffer->* TO <ls_buffer_prev>.
<ls_buffer_prev> = <ls_buffer>.
" this will create/copy a new instance of the table (slow for sorted/hashed)
DELETE TABLE <lt_buffer> FROM <ls_buffer_prev>.
INSERT <ls_buffer_prev> INTO TABLE <lt_buffer>.
EXIT.
ENDLOOP.
ct_tab = <lt_buffer>.
ENDCASE.
" For immediate garbage collection (when trying to prevent fragmentation):
" Run: cl_abap_memory_utilities=>do_garbage_collection( ).
ENDMETHOD.
Comments