ABAP

SAP Memory vs ABAP Memory — 언제 뭘 써야 해? #shorts #SAP #ABAP

▶ YouTube에서 보기

개요와 이 글에서 얻어갈 것

ABAP 개발을 하다 보면 화면이 바뀌어도 값이 살아남아야 하거나, 서브루틴/펑션 모듈로 큰 내부 테이블을 넘겨야 하는 상황이 자주 발생합니다. 이때 등장하는 두 가지 메모리 영역이 바로 SAP MemoryABAP Memory입니다. 이름이 비슷해 혼동하기 쉽지만, 수명(lifetime)과 범위(scope)가 완전히 다릅니다. 이 글에서는 두 메모리의 동작 원리, 실무 사용 패턴, 그리고 프로덕션에서 자주 발생하는 함정을 단계적으로 살펴봅니다.

  • SAP Memory의 SET/GET PARAMETER ID 동작 원리와 SU3 연결
  • ABAP Memory의 EXPORT/IMPORT TO MEMORY ID 사용법
  • 두 메모리의 수명·범위 차이를 도식으로 비교
  • 호출 스택 종료 시 메모리 소멸 시점 이해
  • 실무 시나리오: 화면 간 값 전달 vs 서브루틴 데이터 전송

읽기 전 필요한 배경 지식

이 글은 ABAP 기본 문법(데이터 선언, 내부 테이블, 서브루틴/펑션 모듈 호출)을 알고 있는 중급 개발자를 대상으로 합니다. SE38(리포트), SE80(개발 환경), SE37(펑션 빌더), SU3(사용자 프로파일)에 익숙해야 하며, CALL TRANSACTION/SUBMIT/PERFORM 같은 호출 명령어의 차이를 알고 있으면 더 빠르게 흡수할 수 있습니다.

실습 환경과 버전 정보

이 글의 코드는 SAP NetWeaver AS ABAP 7.5x 이상 환경에서 검증되었습니다. S/4HANA 2022 / 2023 온프레미스, BW/4HANA, ECC 6.0 EHP8 환경에서도 동일하게 동작합니다. ABAP Cloud(Steampunk) 환경에서는 ABAP Memory의 EXPORT/IMPORT TO MEMORY ID 구문이 제한될 수 있으므로, 클라우드 시나리오에서는 ABAP Shared Objects나 ABAP Daemons 같은 대체 기술을 검토해야 합니다.

  • SAP GUI 7.60 이상 (Windows/Java)
  • ABAP Development Tools(ADT) for Eclipse 또는 SE80
  • SU3 트랜잭션 접근 권한 (PID 테스트용)
  • 임시 패키지 또는 $TMP 로컬 객체 작성 권한
  • SE38, SE37, SE11 사용 권한

두 메모리의 본질 차이 - 호텔 vs 회의실 비유

SAP Memory와 ABAP Memory는 데이터를 잠시 보관한다는 점은 같지만, 보관 기간과 접근 가능한 사람이 다릅니다. 비유하자면 SAP Memory는 호텔 객실이고, ABAP Memory는 회의실입니다.

호텔 객실(SAP Memory)은 체크인하면 체크아웃할 때까지 짐을 보관할 수 있습니다. 로비, 식당, 헬스장 어디를 다녀와도 객실에 둔 짐은 그대로 있죠. 마찬가지로 SAP Memory에 SET PARAMETER ID로 저장한 값은 사용자가 로그오프할 때까지 모든 모드(외부 세션)에서 GET PARAMETER ID로 꺼내 쓸 수 있습니다.

회의실(ABAP Memory)은 회의가 끝나면 정리됩니다. 회의 중에는 화이트보드에 자유롭게 적고 자료를 공유할 수 있지만, 회의실을 나가는 순간 모두 지워집니다. ABAP Memory도 같은 내부 세션(internal session, 호출 스택) 내에서만 살아 있고, 메인 프로그램이 끝나면 즉시 소멸합니다.

구분SAP MemoryABAP Memory
저장 명령어SET PARAMETER IDEXPORT TO MEMORY ID
읽기 명령어GET PARAMETER IDIMPORT FROM MEMORY ID
범위(Scope)사용자 세션 전체 (모든 모드)같은 내부 세션 (호출 스택)
수명(Lifetime)로그오프 시까지메인 프로그램 종료 시까지
저장 형태문자열 (PID, SE93/SU3 등록)임의 데이터(구조체/내부테이블)
대표 용도화면 필드 기본값, 사용자 파라미터서브루틴/CALL TRANSACTION 간 데이터 전달

한 가지 더 기억할 점은 외부 세션(external session)과 내부 세션(internal session)의 차이입니다. /OSE38처럼 새 모드를 열면 외부 세션이 새로 생성되고, 한 모드 안에서 CALL TRANSACTION/SUBMIT AND RETURN을 하면 내부 세션이 스택처럼 쌓입니다. ABAP Memory는 내부 세션 호출 체인 내에서만 공유되며, 새 외부 세션을 열면 별도 공간이 됩니다.

단계별 예제 - 기초부터 운영 단계까지

1단계: SAP Memory 기본 사용 (PID 기반 값 전달)

먼저 PID(Parameter ID)를 SE80 또는 SM30(테이블 TPARA)에서 등록합니다. 여기서는 ZCUSTOMER_GRADE라는 PID가 등록되어 있다고 가정합니다. 화면 A에서 고객 등급을 입력하고, 화면 B를 열었을 때 자동으로 기본값으로 표시되는 시나리오입니다.

REPORT z_demo_sap_memory_set.

PARAMETERS: p_grade TYPE c LENGTH 4 DEFAULT 'GOLD'.

START-OF-SELECTION.
  " SAP Memory(파라미터 메모리)에 값 저장
  SET PARAMETER ID 'ZCUSTOMER_GRADE' FIELD p_grade.
  WRITE: / '저장된 등급:', p_grade,
         / 'PID ZCUSTOMER_GRADE 에 보관 완료. 다른 모드에서도 조회 가능.'.

그 다음 별도 리포트에서 값을 꺼내봅니다.

REPORT z_demo_sap_memory_get.

DATA: lv_grade TYPE c LENGTH 4.

START-OF-SELECTION.
  GET PARAMETER ID 'ZCUSTOMER_GRADE' FIELD lv_grade.
  IF sy-subrc = 0.
    WRITE: / '세션 내 저장된 등급:', lv_grade.
  ELSE.
    WRITE: / '해당 PID에 값이 없습니다.'.
  ENDIF.

흥미로운 점은 첫 번째 리포트를 실행한 뒤 /OSE38로 새 모드를 열어 두 번째 리포트를 실행해도 값이 그대로 나온다는 것입니다. 로그오프 후 다시 로그온하면 SU3에 영구 저장된 값이 없다면 사라집니다.

2단계: ABAP Memory 실무 시나리오 (CALL TRANSACTION 간 내부 테이블 전달)

주문 리스트를 표시하는 프로그램에서 특정 주문을 선택하면 후속 트랜잭션을 호출하면서 주문 상세 내역 내부 테이블을 함께 넘기는 패턴입니다. 에러 처리와 로깅도 포함합니다.

REPORT z_demo_abap_memory_export.

TYPES: BEGIN OF ty_order_line,
         order_no   TYPE c LENGTH 10,
         item_no    TYPE i,
         material   TYPE c LENGTH 18,
         quantity   TYPE p LENGTH 5 DECIMALS 2,
       END OF ty_order_line.

DATA: lt_order_lines TYPE STANDARD TABLE OF ty_order_line,
      ls_line        TYPE ty_order_line.

START-OF-SELECTION.
  " 테스트 데이터 구성
  ls_line-order_no = '4500001234'.
  ls_line-item_no  = 10.
  ls_line-material = 'MAT-A-001'.
  ls_line-quantity = '12.50'.
  APPEND ls_line TO lt_order_lines.

  ls_line-item_no  = 20.
  ls_line-material = 'MAT-A-002'.
  ls_line-quantity = '3.00'.
  APPEND ls_line TO lt_order_lines.

  " ABAP Memory로 EXPORT
  EXPORT lt_order_lines FROM lt_order_lines
         TO MEMORY ID 'ZORDER_LINES_TMP'.

  IF sy-subrc <> 0.
    MESSAGE 'ABAP Memory EXPORT 실패' TYPE 'E'.
  ENDIF.

  WRITE: / 'EXPORT 완료. 호출 프로그램 실행...'.

  " 동일 내부 세션에서 다른 리포트 호출
  SUBMIT z_demo_abap_memory_import AND RETURN.
REPORT z_demo_abap_memory_import.

TYPES: BEGIN OF ty_order_line,
         order_no   TYPE c LENGTH 10,
         item_no    TYPE i,
         material   TYPE c LENGTH 18,
         quantity   TYPE p LENGTH 5 DECIMALS 2,
       END OF ty_order_line.

DATA: lt_received TYPE STANDARD TABLE OF ty_order_line.

START-OF-SELECTION.
  IMPORT lt_order_lines TO lt_received
         FROM MEMORY ID 'ZORDER_LINES_TMP'.

  IF sy-subrc = 0 AND lt_received IS NOT INITIAL.
    LOOP AT lt_received INTO DATA(ls_row).
      WRITE: / ls_row-order_no, ls_row-item_no,
               ls_row-material, ls_row-quantity.
    ENDLOOP.
  ELSE.
    WRITE: / 'ABAP Memory에서 데이터를 찾을 수 없습니다.'.
  ENDIF.

  " 사용 후 메모리 정리(권장)
  FREE MEMORY ID 'ZORDER_LINES_TMP'.

핵심은 SUBMIT ... AND RETURN으로 호출하기 때문에 두 리포트가 같은 내부 세션 안에 있다는 점입니다. AND RETURN 없이 SUBMIT만 하면 내부 세션이 끝나면서 메모리가 소멸할 수 있습니다.

3단계: 프로덕션 적용 - 네임스페이스, 정리, 동시성 고려

운영 환경에서는 메모리 ID 충돌을 막기 위해 네임스페이스 접두어를 사용하고, 호출 후 반드시 FREE로 정리하며, 트랜잭션 묶음 단위로 사용 흐름을 캡슐화하는 클래스를 만드는 것이 일반적으로 권장됩니다.

CLASS zcl_order_memory_bridge DEFINITION
  PUBLIC FINAL CREATE PUBLIC.

  PUBLIC SECTION.
    CONSTANTS c_memid TYPE c LENGTH 30 VALUE 'ZBRIDGE_ORDER_PAYLOAD_V1'.

    TYPES: BEGIN OF ty_payload,
             request_id TYPE sysuuid_x16,
             created_at TYPE timestampl,
             lines      TYPE STANDARD TABLE OF string WITH EMPTY KEY,
           END OF ty_payload.

    CLASS-METHODS push
      IMPORTING is_payload TYPE ty_payload
      RAISING   cx_sy_export_no_shared_memory.

    CLASS-METHODS pull
      RETURNING VALUE(rs_payload) TYPE ty_payload.

    CLASS-METHODS clear.
ENDCLASS.

CLASS zcl_order_memory_bridge IMPLEMENTATION.

  METHOD push.
    EXPORT payload = is_payload TO MEMORY ID c_memid.
    IF sy-subrc <> 0.
      RAISE EXCEPTION TYPE cx_sy_export_no_shared_memory.
    ENDIF.
  ENDMETHOD.

  METHOD pull.
    IMPORT payload = rs_payload FROM MEMORY ID c_memid.
    IF sy-subrc <> 0.
      CLEAR rs_payload.
    ENDIF.
  ENDMETHOD.

  METHOD clear.
    FREE MEMORY ID c_memid.
  ENDMETHOD.

ENDCLASS.

SAP Memory에도 운영 패턴을 적용하면, 사용자 기본값을 SU3에 등록된 PID로 동기화하는 도우미 클래스를 만들 수 있습니다.

CLASS zcl_user_default_helper DEFINITION
  PUBLIC FINAL CREATE PUBLIC.

  PUBLIC SECTION.
    CLASS-METHODS remember_plant
      IMPORTING iv_plant TYPE c.

    CLASS-METHODS recall_plant
      RETURNING VALUE(rv_plant) TYPE c LENGTH 4.
ENDCLASS.

CLASS zcl_user_default_helper IMPLEMENTATION.

  METHOD remember_plant.
    SET PARAMETER ID 'WRK' FIELD iv_plant.   " WRK는 표준 PID
  ENDMETHOD.

  METHOD recall_plant.
    GET PARAMETER ID 'WRK' FIELD rv_plant.
  ENDMETHOD.

ENDCLASS.

이렇게 캡슐화하면 단위 테스트(ABAP Unit)에서 PID 의존성을 모의(mocking)하기 쉬워지고, 운영 코드에서 SAP Memory와 ABAP Memory의 호출 위치를 한 곳으로 모을 수 있어 보안 점검과 성능 분석에 유리합니다.

자주 빠지는 함정과 트러블슈팅

Q1. EXPORT는 성공했는데 IMPORT에서 데이터가 비어 있습니다.

대부분 호출 방식 문제입니다. SUBMIT은 기본적으로 새 내부 세션을 만들고 끝나면 메모리를 비웁니다. 같은 호출 스택을 유지하려면 SUBMIT ... AND RETURN, 또는 CALL TRANSACTION ... AND SKIP FIRST SCREEN을 사용해야 합니다. 또한 EXPORT와 IMPORT의 변수명(필드 라벨)을 동일하게 맞춰야 하며, 다를 경우 EXPORT name1 = data1 / IMPORT name1 = data1 처럼 명시적으로 매핑해야 합니다.

Q2. SET PARAMETER ID에서 PID does not exist 오류가 납니다.

해당 PID가 TPARA 테이블(SE80에서 Parameter ID 객체)로 등록되어 있어야 합니다. 미등록 PID에 SET을 시도하면 런타임 예외 또는 sy-subrc 4가 발생합니다. 커스텀 PID는 반드시 Z/Y 네임스페이스로 만들고, 트랜스포트로 운영기에 이관해야 합니다.

Q3. ABAP Memory에 대용량 내부 테이블을 넣어도 안전한가요?

ABAP Memory는 사용자 세션의 롤 영역(roll area)에 보관되므로 메모리 한도(abap/heap_area_dia, ztta/roll_area 등)에 영향을 줍니다. 수십만 건 이상을 EXPORT하면 TSV_TNEW_PAGE_ALLOC_FAILED 같은 메모리 부족 덤프가 발생할 수 있습니다. 대량 데이터는 ABAP Shared Memory Objects(SHMA) 또는 임시 DB 테이블로 옮기는 것이 일반적으로 권장됩니다.

Q4. 멀티 모드에서 PID가 동기화되지 않습니다.

SET PARAMETER ID로 저장한 값은 현재 모드뿐 아니라 같은 사용자 세션의 다른 모드에서도 즉시 보입니다. 다만 모드 사이의 갱신은 화면 진입 시점에 GET되므로, 이미 떠 있는 화면의 필드 값을 자동으로 바꾸지는 않습니다. 화면 새로고침 또는 PBO 재실행 시점에 반영됩니다.

Q5. FREE를 안 하면 메모리 누수가 생기나요?

로그오프 시 SAP Memory는 모두 해제되고, 메인 프로그램 종료 시 ABAP Memory도 모두 해제됩니다. 다만 장기 실행 백그라운드 잡에서 동일 ID로 반복 EXPORT하면 이전 데이터가 덮어쓰여 일관성 문제가 생길 수 있으므로, 사용 직후 FREE MEMORY ID를 호출하는 습관이 권장됩니다.

이어서 살펴보면 좋은 관련 주제

SAP Memory/ABAP Memory를 충분히 익혔다면, 보다 큰 데이터나 복잡한 동시성 요구가 있는 상황에서는 다음 기술을 검토해 보세요. ABAP Shared Memory Objects는 여러 세션 간에 읽기 전용 캐시를 공유할 때 적합하고, ABAP Shared Buffer(EXPORT TO SHARED BUFFER)는 어플리케이션 서버 단위 휘발성 캐시로 사용됩니다. ABAP Cloud(Steampunk) 환경에서는 메모리 ID 기반 API가 제한적이므로, RAP(ABAP RESTful Application Programming Model)의 Behavior Implementation Class나 Transactional Buffer 패턴으로 대체합니다. 화면 간 사용자 기본값은 SU3 Parameters 외에 Personalization API(USR05, sap_user_personas)도 함께 살펴보면 좋습니다.

더 깊이 읽어볼 만한 자료

댓글 0

아직 댓글이 없습니다.