So I understand what it's used for and I know how to use it but, what exactly is it I create? Is it a List or an Array or what? When I build a StandardSetController in the following way

public ApexPages.StandardSetController setCon {
   get {
      if(setCon == null) {
         setCon = new ApexPages.StandardSetController(calendarEvents);
         noOfRecords = setCon.getResultSize();
      return setCon;

where calendarEvents is a list of Campaigns, do I now have 2 lists with the same campaigns in them but setCon just has some additional functions? Basically, I don't want to duplicate my data.

Sorry if this is a stupid question but I can't seem to find an actual explanation anywhere. Thanks for your help.

  • 1
    Hi hunty. Thanks for asking! I really enjoyed figuring out how these things work internally (I never thought to try before).
    – sfdcfox
    Sep 21, 2016 at 13:36

1 Answer 1


StandardSetController can be created one of two ways, one being from a List<SObject>, and one being from a Database.QueryLocator. If you use the first form, it creates an internal backing array plus two Integer variables (page size and current page).

Here's proof:

Account[] accounts = new Account[0];
while(accounts.size()<1000) accounts.add(new Account(Name='test'));
Integer heap1 = Limits.getHeapSize();
ApexPages.StandardSetController c = new ApexPages.StandardSetController(accounts);
Integer heap2 = Limits.getHeapSize();
System.debug('Before StandardSetController: '+heap1);
System.debug('After StandardSetController: '+heap2);
System.debug('StandardSetController size: '+(heap2-heap1));

Output (should be consistent across all orgs):

DEBUG|Before StandardSetController: 21061
DEBUG|After StandardSetController: 25069
DEBUG|StandardSetController size: 4008

Every element in an array requires 4 bytes, and the two additional backing variables means that we use 1002*4 bytes (4008). You will observe the same heap usage using List.clone() (plus or minus a few bytes).

If you use a QueryLocator, then you end up with memory usage consistent with one page worth of data. Again, we demonstrate this using heap limits:

ApexPages.StandardSetController c = new ApexPages.StandardSetController(Database.getQueryLocator([SELECT Name FROM Account]));
Integer heap1 = Limits.getHeapSize();
System.debug('StandardSetController: '+heap1);
Integer heap2 = Limits.getHeapSize();
System.debug('StandardSetController resized: '+heap2);

Output (note: actual numbers will vary based on record data):

DEBUG|StandardSetController: 1049
DEBUG|StandardSetController resized: 5855

In other words, memory usage will be just enough to store the page size, the current page, the QueryLocator, and the current page of records.

So, in conclusion, they do require some memory, but not as much as a full copy of the data.

  • 1
    Thank you @sfdcfox, brilliant answer. Really appreciate it.
    – hunty
    Sep 21, 2016 at 13:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .