Memory Management in ABAP ermöglicht den Datenaustausch zwischen Programmen. Es gibt verschiedene Speicherbereiche: ABAP Memory, SAP Memory, Datenbank-Cluster und Shared Objects.
Speicherbereiche
| Bereich | Lebensdauer | Verwendung |
|---|---|---|
| ABAP Memory | Session (Call Stack) | Zwischen CALL TRANSACTION |
| SAP Memory | Benutzer-Session | Zwischen Transaktionen |
| Database Cluster | Persistent | Über Sessions hinweg |
| Shared Objects | Applikationsserver | Zwischen Benutzern |
Beispiele
1. ABAP Memory (EXPORT/IMPORT TO MEMORY)
" Programm 1: Daten exportierenDATA: ls_customer TYPE kna1, lt_orders TYPE TABLE OF vbak.
" Daten vorbereitenls_customer-kunnr = '0000001000'.ls_customer-name1 = 'Mustermann GmbH'.
" In ABAP Memory exportierenEXPORT customer = ls_customer orders = lt_orders TO MEMORY ID 'ZCUSTOMER_DATA'.
" Programm 2: Daten importieren (nach CALL TRANSACTION)DATA: ls_customer TYPE kna1, lt_orders TYPE TABLE OF vbak.
IMPORT customer = ls_customer orders = lt_orders FROM MEMORY ID 'ZCUSTOMER_DATA'.
IF sy-subrc = 0. WRITE: / 'Kunde:', ls_customer-name1.ENDIF.
" Memory freigebenFREE MEMORY ID 'ZCUSTOMER_DATA'.2. SAP Memory (SET/GET PARAMETER)
" SAP Memory für Feldvorbelegung" Parameter-IDs sind im Data Dictionary definiert
" Wert setzenSET PARAMETER ID 'KUN' FIELD '0000001000'.SET PARAMETER ID 'BUK' FIELD '1000'.
" Wert lesenDATA: lv_kunnr TYPE kunnr, lv_bukrs TYPE bukrs.
GET PARAMETER ID 'KUN' FIELD lv_kunnr.GET PARAMETER ID 'BUK' FIELD lv_bukrs.
WRITE: / 'Kunde:', lv_kunnr, / 'Buchungskreis:', lv_bukrs.
" Transaktion mit vorbelegten Werten aufrufenSET PARAMETER ID 'KUN' FIELD '0000001000'.CALL TRANSACTION 'XD03' AND SKIP FIRST SCREEN.3. Datenbank-Cluster (EXPORT/IMPORT TO DATABASE)
" Persistente Speicherung über Sessions hinweg" Tabelle: INDX oder eigene Cluster-Tabelle
DATA: ls_settings TYPE ty_settings.
ls_settings-user = sy-uname.ls_settings-variant = 'DEFAULT'.ls_settings-values = lt_values.
" In Datenbank speichernEXPORT settings = ls_settings TO DATABASE indx(zs) " Tabelle INDX, Area 'ZS' ID |SETTINGS_{ sy-uname }|. " Eindeutiger Schlüssel
" Später wieder lesenDATA: ls_settings TYPE ty_settings.
IMPORT settings = ls_settings FROM DATABASE indx(zs) ID |SETTINGS_{ sy-uname }|.
IF sy-subrc = 0. " Settings gefunden WRITE: / 'Variante:', ls_settings-variant.ENDIF.
" LöschenDELETE FROM DATABASE indx(zs) ID |SETTINGS_{ sy-uname }|.4. Eigene Cluster-Tabelle
" Tabelle in SE11 anlegen:" Name: ZCUSTOM_CLUSTER" Felder:" - RELID (CHAR 2) - Area" - SRTFD (CHAR 40) - ID/Schlüssel" - Cluster-Felder (CLUSTR, CLUSTD)
" VerwendungEXPORT data = ls_data TO DATABASE zcustom_cluster(AA) ID lv_key.
IMPORT data = ls_data FROM DATABASE zcustom_cluster(AA) ID lv_key.5. Shared Objects (Applikationsserver-Cache)
" 1. Area-Klasse definieren (SE24)CLASS zcl_shared_area DEFINITION PUBLIC FINAL CREATE PUBLIC SHARED MEMORY ENABLED.
PUBLIC SECTION. INTERFACES: if_shm_build_instance.
DATA: mt_customers TYPE HASHED TABLE OF kna1 WITH UNIQUE KEY kunnr.
METHODS: load_customers.ENDCLASS.
CLASS zcl_shared_area IMPLEMENTATION. METHOD if_shm_build_instance~build. " Wird aufgerufen wenn Area gebaut wird DATA(lo_area) = CAST zcl_shared_area( bound_memory ). lo_area->load_customers( ). ENDMETHOD.
METHOD load_customers. SELECT * FROM kna1 INTO TABLE mt_customers UP TO 10000 ROWS. ENDMETHOD.ENDCLASS.
" 2. Shared Memory Area in SHMA erstellen" Name: ZSM_CUSTOMER_CACHE" Root-Klasse: ZCL_SHARED_AREA
" 3. VerwendungDATA: lo_area TYPE REF TO zcl_shared_area, lo_handle TYPE REF TO zcl_sm_customer_cache.
TRY. " Lesezugriff lo_handle = zcl_sm_customer_cache=>attach_for_read( ). lo_area = CAST zcl_shared_area( lo_handle->root ).
" Daten nutzen READ TABLE lo_area->mt_customers INTO DATA(ls_customer) WITH KEY kunnr = '0000001000'.
lo_handle->detach( ).
CATCH cx_shm_attach_error INTO DATA(lx_error). " Area existiert noch nicht -> bauen TRY. zcl_sm_customer_cache=>build( EXPORTING inst_name = zcl_sm_customer_cache=>default_instance ). CATCH cx_shm_build_error. ENDTRY.ENDTRY.6. Memory zwischen CALL TRANSACTION
" HauptprogrammDATA: ls_order TYPE vbak.
ls_order-vbeln = '0000000001'.ls_order-kunnr = '0000001000'.
" Daten für gerufenes Programm bereitstellenEXPORT order = ls_order TO MEMORY ID 'ZORDER_EDIT'.
" Transaktion aufrufenCALL TRANSACTION 'ZORDER_CHANGE'.
" Nach Rückkehr: Geänderte Daten lesenIMPORT order = ls_order FROM MEMORY ID 'ZORDER_EDIT'.FREE MEMORY ID 'ZORDER_EDIT'.
" Gerufenes Programm (ZORDER_CHANGE)DATA: ls_order TYPE vbak.
IMPORT order = ls_order FROM MEMORY ID 'ZORDER_EDIT'.
" Bearbeitung...
" Geänderte Daten zurückgebenEXPORT order = ls_order TO MEMORY ID 'ZORDER_EDIT'.
LEAVE PROGRAM.7. Memory Helper Klasse
CLASS zcl_memory_helper DEFINITION. PUBLIC SECTION. " ABAP Memory CLASS-METHODS: export_to_memory IMPORTING iv_id TYPE clike iv_data TYPE any.
CLASS-METHODS: import_from_memory IMPORTING iv_id TYPE clike EXPORTING ev_data TYPE any RETURNING VALUE(rv_found) TYPE abap_bool.
CLASS-METHODS: free_memory IMPORTING iv_id TYPE clike.
" SAP Memory CLASS-METHODS: set_parameter IMPORTING iv_id TYPE clike iv_value TYPE clike.
CLASS-METHODS: get_parameter IMPORTING iv_id TYPE clike RETURNING VALUE(rv_value) TYPE string.
" Database Cluster CLASS-METHODS: save_to_db IMPORTING iv_id TYPE clike iv_data TYPE any.
CLASS-METHODS: load_from_db IMPORTING iv_id TYPE clike EXPORTING ev_data TYPE any RETURNING VALUE(rv_found) TYPE abap_bool.
CLASS-METHODS: delete_from_db IMPORTING iv_id TYPE clike.ENDCLASS.
CLASS zcl_memory_helper IMPLEMENTATION. METHOD export_to_memory. EXPORT data = iv_data TO MEMORY ID iv_id. ENDMETHOD.
METHOD import_from_memory. IMPORT data = ev_data FROM MEMORY ID iv_id. rv_found = xsdbool( sy-subrc = 0 ). ENDMETHOD.
METHOD free_memory. FREE MEMORY ID iv_id. ENDMETHOD.
METHOD set_parameter. SET PARAMETER ID iv_id FIELD iv_value. ENDMETHOD.
METHOD get_parameter. GET PARAMETER ID iv_id FIELD rv_value. ENDMETHOD.
METHOD save_to_db. DATA(lv_id) = CONV indx_srtfd( iv_id ). EXPORT data = iv_data TO DATABASE indx(zm) ID lv_id. COMMIT WORK. ENDMETHOD.
METHOD load_from_db. DATA(lv_id) = CONV indx_srtfd( iv_id ). IMPORT data = ev_data FROM DATABASE indx(zm) ID lv_id. rv_found = xsdbool( sy-subrc = 0 ). ENDMETHOD.
METHOD delete_from_db. DATA(lv_id) = CONV indx_srtfd( iv_id ). DELETE FROM DATABASE indx(zm) ID lv_id. COMMIT WORK. ENDMETHOD.ENDCLASS.
" Verwendung" ABAP Memoryzcl_memory_helper=>export_to_memory( iv_id = 'MY_DATA' iv_data = ls_data).
IF zcl_memory_helper=>import_from_memory( iv_id = 'MY_DATA' IMPORTING ev_data = ls_data ) = abap_true. " Daten gefundenENDIF.
" Databasezcl_memory_helper=>save_to_db( iv_id = |USER_{ sy-uname }_SETTINGS| iv_data = ls_settings).8. Benutzer-spezifische Einstellungen
CLASS zcl_user_settings DEFINITION. PUBLIC SECTION. TYPES: BEGIN OF ty_settings, layout TYPE string, pagesize TYPE i, filters TYPE string, END OF ty_settings.
METHODS: constructor IMPORTING iv_program TYPE sy-repid DEFAULT sy-repid.
METHODS: load RETURNING VALUE(rs_settings) TYPE ty_settings.
METHODS: save IMPORTING is_settings TYPE ty_settings.
METHODS: delete.
PRIVATE SECTION. DATA: mv_id TYPE indx_srtfd.ENDCLASS.
CLASS zcl_user_settings IMPLEMENTATION. METHOD constructor. mv_id = |{ iv_program }_{ sy-uname }|. ENDMETHOD.
METHOD load. IMPORT settings = rs_settings FROM DATABASE indx(us) ID mv_id.
IF sy-subrc <> 0. " Defaults rs_settings-pagesize = 100. ENDIF. ENDMETHOD.
METHOD save. EXPORT settings = is_settings TO DATABASE indx(us) ID mv_id. COMMIT WORK. ENDMETHOD.
METHOD delete. DELETE FROM DATABASE indx(us) ID mv_id. COMMIT WORK. ENDMETHOD.ENDCLASS.
" VerwendungDATA(lo_settings) = NEW zcl_user_settings( ).DATA(ls_settings) = lo_settings->load( ).
" Einstellungen ändernls_settings-pagesize = 50.lo_settings->save( ls_settings ).9. Session-übergreifender Cache
" Shared Memory für häufig benötigte Stammdaten
" Area Root KlasseCLASS zcl_material_cache DEFINITION PUBLIC FINAL CREATE PUBLIC SHARED MEMORY ENABLED.
PUBLIC SECTION. INTERFACES: if_shm_build_instance.
TYPES: ty_materials TYPE HASHED TABLE OF mara WITH UNIQUE KEY matnr.
DATA: mt_materials TYPE ty_materials, mv_loaded_at TYPE timestampl.
METHODS: get_material IMPORTING iv_matnr TYPE matnr RETURNING VALUE(rs_material) TYPE mara.
METHODS: is_expired RETURNING VALUE(rv_expired) TYPE abap_bool.ENDCLASS.
CLASS zcl_material_cache IMPLEMENTATION. METHOD if_shm_build_instance~build. DATA(lo_root) = CAST zcl_material_cache( bound_memory ).
SELECT * FROM mara INTO TABLE lo_root->mt_materials WHERE mtart IN ('FERT', 'HALB', 'ROH').
GET TIME STAMP FIELD lo_root->mv_loaded_at. ENDMETHOD.
METHOD get_material. READ TABLE mt_materials INTO rs_material WITH KEY matnr = iv_matnr. ENDMETHOD.
METHOD is_expired. DATA: lv_now TYPE timestampl. GET TIME STAMP FIELD lv_now.
" Cache nach 1 Stunde invalidieren rv_expired = xsdbool( lv_now - mv_loaded_at > 3600 ). ENDMETHOD.ENDCLASS.
" VerwendungDATA: lo_handle TYPE REF TO zcl_sm_material, lo_cache TYPE REF TO zcl_material_cache.
TRY. lo_handle = zcl_sm_material=>attach_for_read( ). lo_cache = lo_handle->root.
" Cache-Validität prüfen IF lo_cache->is_expired( ). lo_handle->detach( ). zcl_sm_material=>invalidate_instance( ). " Beim nächsten Zugriff wird neu gebaut ELSE. DATA(ls_material) = lo_cache->get_material( lv_matnr ). lo_handle->detach( ). ENDIF.
CATCH cx_shm_attach_error. " Fallback: Direkt aus DB SELECT SINGLE * FROM mara WHERE matnr = @lv_matnr INTO @ls_material.ENDTRY.10. EXPORT/IMPORT mit Kompression
" Für große Datenmengen: KompressionDATA: lt_big_table TYPE TABLE OF vbak, lv_xstring TYPE xstring.
" Daten in komprimiertes XStringEXPORT data = lt_big_table TO DATA BUFFER lv_xstring COMPRESSION ON.
" In DB speichernUPDATE zcache SET data = lv_xstring WHERE id = lv_id.
" Wieder ladenSELECT SINGLE data FROM zcache WHERE id = @lv_id INTO @lv_xstring.
IMPORT data = lt_big_table FROM DATA BUFFER lv_xstring.11. Memory im Fehlerfall freigeben
" TRY-CLEANUP für sauberes AufräumenDATA: lv_memory_id TYPE c LENGTH 30 VALUE 'ZTEMP_DATA'.
TRY. EXPORT data = ls_data TO MEMORY ID lv_memory_id.
" Verarbeitung die fehlschlagen kann process_data( ).
" Normal freigeben FREE MEMORY ID lv_memory_id.
CATCH cx_root INTO DATA(lx_error). " Auch im Fehlerfall freigeben FREE MEMORY ID lv_memory_id. RAISE EXCEPTION lx_error.ENDTRY.
" Oder mit CLEANUPTRY. EXPORT data = ls_data TO MEMORY ID lv_memory_id. process_data( ).
CLEANUP. " Wird bei Exception automatisch ausgeführt FREE MEMORY ID lv_memory_id.ENDTRY.12. Datenübertragung an Report
" Hauptprogramm: Daten an Report übergebenDATA: lt_selections TYPE TABLE OF rsparams.
" Daten exportierenEXPORT selections = lt_selections TO MEMORY ID 'ZREPORT_DATA'.
" Report aufrufenSUBMIT zreport_process AND RETURN.
" Ergebnis abholenDATA: lt_results TYPE ty_result_tab.IMPORT results = lt_results FROM MEMORY ID 'ZREPORT_RESULTS'.
FREE MEMORY ID 'ZREPORT_DATA'.FREE MEMORY ID 'ZREPORT_RESULTS'.
" Report (ZREPORT_PROCESS)DATA: lt_selections TYPE TABLE OF rsparams, lt_results TYPE ty_result_tab.
" Daten vom AufruferIMPORT selections = lt_selections FROM MEMORY ID 'ZREPORT_DATA'.
" Verarbeitung...
" Ergebnis zurückgebenEXPORT results = lt_results TO MEMORY ID 'ZREPORT_RESULTS'.Speicherbereich-Übersicht
| Methode | Syntax | Bereich |
|---|---|---|
EXPORT TO MEMORY | ID ‘xyz’ | ABAP Memory |
SET PARAMETER | ID ‘PAR’ | SAP Memory |
EXPORT TO DATABASE | indx(xx) ID ‘xyz’ | DB Cluster |
EXPORT TO DATA BUFFER | xstring | Variable |
| Shared Memory | CL_SHM_AREA | Applikationsserver |
Wichtige Hinweise / Best Practice
- FREE MEMORY aufrufen wenn Daten nicht mehr benötigt.
- Eindeutige IDs verwenden (z.B. mit Programm/User).
- ABAP Memory nur innerhalb eines Call Stacks.
- SAP Memory für Feldvorbelegung (Parameter-IDs).
- Database Cluster für persistente Daten.
- Shared Objects für Server-weites Caching.
- COMPRESSION ON für große Datenmengen.
- CLEANUP für Aufräumen bei Exceptions.
- Memory-IDs nicht zu lang (max. 72 Zeichen).
- Kombinieren Sie mit Background Jobs für Datenübergabe.