Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Table expression - Valid v/s Invalid data references

SuhaSaha
Advisor
Advisor
0 Kudos

Hello all,

I ran into a ABAP trapdoor today. Here goes the code snippet:

CLASS lcl_test_memory DEFINITION CREATE PUBLIC.


  PUBLIC SECTION.
    DATA: clients TYPE SORTED TABLE OF t000
                  WITH UNIQUE KEY mandt
                  READ-ONLY.
    METHODS:
      constructor,
      get_invalid_ref
        IMPORTING
          iv_client      TYPE symandt
        RETURNING
          VALUE(rd_data) TYPE REF TO data,
      get_valid_ref
        IMPORTING
          iv_client      TYPE symandt
        RETURNING
          VALUE(rd_data) TYPE REF TO data.
  PROTECTED SECTION.
  PRIVATE SECTION.


ENDCLASS.


CLASS lcl_test_memory IMPLEMENTATION.


  METHOD constructor.
    SELECT *
      FROM t000
      INTO TABLE @clients.
  ENDMETHOD.


  METHOD get_invalid_ref.


    DATA(ls_client) = VALUE #( clients[ mandt = iv_client ] ).


    rd_data = REF #( ls_client ).


  ENDMETHOD.


  METHOD get_valid_ref.
    rd_data = REF #( clients[ mandt = iv_client ] ).
  ENDMETHOD.


ENDCLASS.


START-OF-SELECTION.
  DATA(gd_invalid) = NEW lcl_test_memory( )->get_invalid_ref( sy-mandt ).
  DATA(gd_valid) = NEW lcl_test_memory( )->get_valid_ref( sy-mandt ).

I have already read the blogs from Horst and Jerry, so the cause of the "invalid" data reference is already clear. Although i must admit that i had already been through the trapdoor 😞

However when i use the REF operator together with the table expression inline, i get back a valid data reference. Why?

As usual i looked up the ABAP documentation, what stuck me is the following -

When applied to data objects in the heap GET REFERENCE creates memory-retaining heap references.

Since "heap" contains anonymous data objects, does the table expression generate an anonymous data object? I looked up the documentation and couldn't find anything which answers my question.

Can anyone provide me an explanation? How does one avoid this trapdoor?

BR,

Suhas

PS - I am working on ABAP 750 SP06 release

1 ACCEPTED SOLUTION

fabianlupa
Contributor

Not much of a trapdoor I don't think. In your second method you "retain" a valid data reference because you did not copy your table expression result to a local variable that is garbage collected / out of scope once you leave the method. In get_invalid_ref the reference points towards the local variable! The instance attribute clients still exists after you leave the method.

The memory retaining heap references I think just means that the object instance with the referenced attribute will not be garbage collected once you free all the references to it because data references to member attributes of it also count towards the "reference counter" which needs to be zero for garbage collection to be able to occur.

As you can see in the screenshot the second instance of lcl_test_memory is still in memory (0:8*) even though go_b is cleared and manual garbage collection was invoked.

7 REPLIES 7

fabianlupa
Contributor

Not much of a trapdoor I don't think. In your second method you "retain" a valid data reference because you did not copy your table expression result to a local variable that is garbage collected / out of scope once you leave the method. In get_invalid_ref the reference points towards the local variable! The instance attribute clients still exists after you leave the method.

The memory retaining heap references I think just means that the object instance with the referenced attribute will not be garbage collected once you free all the references to it because data references to member attributes of it also count towards the "reference counter" which needs to be zero for garbage collection to be able to occur.

As you can see in the screenshot the second instance of lcl_test_memory is still in memory (0:8*) even though go_b is cleared and manual garbage collection was invoked.

horst_keller
Product and Topic Expert
Product and Topic Expert
0 Kudos

Yep

0 Kudos

Thanks for the clarification!

I always thought that the "functional" operators create anonymous data objects, hence "trapdoor".

horst_keller
Product and Topic Expert
Product and Topic Expert

Heap, "Part of the program memory in which anonymous data objects and instances of classes created dynamically using CREATE DATA, CREATE OBJECT, or NEW are saved. The allocated memory can be released again by the garbage collector."

The instance of your class lies in the heap. What is the instance of a class else but it's attributes?

As you say yourself:

"When applied to data objects in the heap GET REFERENCE creates memory-retaining heap references."

You apply REF (same as GET REFERENCE) to the instance attribute of an object in the heap and by that keep the whole object alive.

heap reference: Reference to an object or part of an object in the heap. A heap reference keeps an object alive.

0 Kudos

Slightly off topic but i couldn't find any difference between generic types - any & data? Is there a guideline on when to use which one?

horst_keller
Product and Topic Expert
Product and Topic Expert

Used directly behind TYPE, there is no difference:

TYPE any is the same as TYPE data.(for historic reasons).

Behind REF TO, there is a difference:

You can say TYPE REF TO data and TYPE REF TO object but not TYPE REF TO any.

TYPE REF TO any would be a generic reference variable that could point to data objects and instances of classes. This was never implemented, because then the question arises, what is the meaning of TYPE any, which - unfortunately - is older than TYPE data.

From that said, it would clearer to use TYPE data, but in fact nobody cares ...

0 Kudos

Thanks for clarifying it up!