Currently Being Moderated

In the old R/3 days, ABAP programmers rarely needed to analyze memory consumption in their programs.  The simple and robust ABAP memory model made it very hard for anyone to program a serious ABAP memory leak.

With the addition of more types of dynamic memory objects – not just internal tables, but also strings, anonymous data objects, boxed components – and a trend toward transactions that live longer, it’s now possible to write an ABAP program that can run into memory problems.

Since ABAP programmers can no longer ignore memory consumption, the ABAP Workbench has greatly enhanced the memory analysis tools in the New ABAP Debugger and in the Memory Inspector (transaction SMI or S_MEMORY_INSPECTOR).

This weblog showcases the enhancements that come with EHP2:

  • The Dominator Tree (or keep-alive tree) for containment hierarchies in memory objects – which runtime entity is keeping which memory object alive. This new analysis tool is offered in both the New ABAP Debugger and in the Memory Inspector. 
  • The Memory Object Explorer in the New ABAP Debugger, for navigating up and down through the memory objects in the keep-alive hierarchy of objects. Starting from any memory object, you can navigate up to its parents or down to its children, and you can take a look at the contents of each memory object.
  • A separate weblog shows you the new Application-specific memory analysis tools in the New ABAP Debugger – for looking at the memory consumption of ABAP Web Dynpro applications. There is also a similar tool for analyzing Web Service / HTTP applications.

You may also notice that doing memory analysis in the debugger is much more comfortable, and that we have made improvements in the user interface in the Memory Inspector as well. But we do not go into these UI changes in detail, nor will we look at the Memory Inspector transaction in this blog.

The New Features in Practice in the Debugger

You do memory analysis usually for one of two purposes:

  • You want to see how big your program – or objects in it - are in terms of memory consumption. Is it bigger than you expect?  Usually you’re in the New ABAP Debugger when you do this.
  • You want to see whether you have a memory leak. Does the memory consumption of your program change over time?  Or – how did it get so big that it dumped because of lack of memory – this question also sometimes comes up.

Usually, you’re comparing memory snapshots in the Memory Inspector (transaction SMI) when you’re doing this type of analysis.

Let’s see how the new memory analysis features work if you are in the debugger, just checking how much memory your program uses. Maybe you’re just being cautious in doing this checking – or maybe you’ve learned:  a long-running transaction or service with lots of dynamic memory objects means, you better check the memory consumption before your customers find out about it for you.  What you see here on the new memory analysis features applies just as well in the separate Memory Inspector transaction.

A Comfortable Quick Look at Memory Consumption – The Memory Analysis Tab

You don’t have to switch to a memory analysis tool anymore to see how much memory objects in your program are using.  There’s a new Memory Analysis tab in the new ABAP Debugger, on the Variable Fast Display. Just switch to the tab, click on a variable in your program, and you can see how much memory the object uses.

The Memory Analysis Tab in the ABAP Debugger 

Here we have two tables that have the same number of rows, and we happen to know that they contain the same data - except that IT_CUSTOMERS contains extra data.  Even so, IT_CUSTOMERS is smaller in memory.  How is the difference explained?   Does IT_CUSTOMERS offer a more efficient way to organize the table?  A closer look shows that we don’t understand how IT_CUSTOMERS is organized. The table statistics don’t seem to match the memory size.

  • The size of table IT_SCUSTOM is okay – 4637 rows of 16 fields with a row-length of 464 bytes is close to the Bound Used Memory (bound memory is the memory that would be freed if the table were cleared) plus some management overhead.   The table simply is that big.
  • The size of IT_CUSTOMERS is puzzling. It has the same number of rows as IT_SCUSTOM but a row length of 32 bytes. No way that the table body itself comes close to 1.7 million bytes of bound memory.

Analyzing Table IT_CUSTOMERS with the Memory Analysis Tool

To study table IT_CUSTOMERS, you activate the Memory Analysis Tool by choosing the New Tool or Replace Tool button, opening the Memory Management folder, and clicking on Memory Analysis.

 image

The tool that was available before EHP2 was the Memory Objects view, shown below in its form in NetWeaver 7.0 EHP2. This tool shows you the memory objects of the program (the representations of dynamic variables in the memory management system) ranked by size. 

Memory Objects also shows you which variables reference each memory object.  But the view does not help us to understand the differences between the IT_CUSTOMERS and IT_SCUSTOM tables. Essentially we just have an unstructured list of memory objects ranked by size.

 image

Here’s where the new Dominator Tree view (below) shows how useful it is.  In this view, it’s immediately clear how IT_CUSTOMERS is structured. The rows are so short because they contain only an object reference. The CUSTOMER objects in the table contain, by the way, a further object, ACCOUNT.  The CUSTOMER objects are also keeping several strings – variables NAME, ADDRESS, and CITY - alive.  The bound storage of the table is so high because the table is keeping all of the customer object hierarchies alive.  (Without the references from IT_CUSTOMER, the ABAP garbage collector would clear the objects away and free the memory.)

image 

The organization of the table is now clear. Where does the advantage in memory use of the IT_CUSTOMERS table come from, compared to table IT_SCUSTOM? 

To find the answer, you could copy the name of a CUSTOMER object into the clipboard, and start the Memory Object Explorer (available only in the debugger, not in the Memory Inspector). In the Memory Object Explorer (below), we can follow edges from the CUSTOMER object to its children, all of the objects that it references.

The Dominator Tree shows only strings and instances of classes that belong to the bound storage of each CUSTOMER class object. These are the objects that CUSTOMER keeps alive. The Memory Object Explorer, by contrast, also shows objects that are referenced by more than one CUSTOMER instance, memory objects that are in effect shared. Can it be that sharing of objects accounts for the reduced storage use?

We follow a CUSTOMER object to its referenced objects and then check some of the referenced objects themselves in the Explorer. COUNTRY looks like a good variable to check for sharing among multiple CUSTOMER objects. So we go from string {S:S9} ADDRESS-COUNTRY up the memory hierarchy – Higher-Level Memory Objects - to see the parents of this string, objects that reference this string.

image 

And in fact, as you can see below, the more efficient storage use in table IT_CUSTOMERS than in IT_SCUSTOM could be due to massive sharing of string objects in memory.  There are many CUSTOMER objects from our table that reference the same COUNTRY string.

image 

The IT_CUSTOMERS table design takes advantage of the fact that string variables that have the same content share a single memory object.  (See ‘value semantic’ in the ABAP Online Help (transaction ABAPHELP or at help.sap.com).  ABAP gives a string or other value-semantic object its own memory object only on an as-needed basis – if the string is changed.

In many applications, a table like this list of customers is rarely changed, but is used instead to guide processing. In this case, it may make sense to make use of memory object sharing to reduce storage consumption.  In this application, CUSTOMER attributes like the country-of-residence reference the same string, as long as the same country is being referenced.  You can check out whether the strategy is really worthwhile – when filling a table, when reading a table, in the event that object attributes are changed – by doing some testing of the alternatives in the ABAP Runtime Analysis, transaction SAT. (See the weblogs by Olga Dolinskaja on the new SAT.)

An advantage of doing memory analysis in the debugger is that you can see what the value of the variables is. This is something that you cannot do when you analyze memory snapshots in the Memory Inspector (transaction SMI).  A double click on string {S:S9} above shows us what country all of those customers inhabit:

 Displaying the Value of a Memory Object in the ABAP Debugger

But the Memory Inspector, in turn, has the advantage of being able to compare memory snapshots and show changes in memory use over time. That’s an invaluable capability for checking for leaks in a long-running ABAP application.

Comments

Actions

Filter Blog

By date:
By tag: