About Me

My photo
PLANO, Texas, United States

Sunday, August 17, 2014

Heap Size

A stack is a place in the computer memory where all the variables that are declared and initialized before runtime are stored. The heap is the section of computer memory where all the variables created or initialized at runtime are stored. On the other hand, the heap is an area of memory used for dynamic memory allocation.

  • When you create objects in Apex code memory is allocated to store the objects. And that memory is allocated from the allocated heap. Think of it as a designated amount of memory you can use up in your Apex request.

  • Heap play an important role when your application runs, Bad code quality can consume the heap size badly and which impact the performance of your application

Apex heap size too large
  • As you know heap is important to allocate the memory at runtime and hence we should be very careful while writing the code and must ensure to take care of heap size. If the heap size is huge, it will surely impact the performance of the application and the application will get slow. 

  • Salesforce enforces an Apex Heap Size Limit of 6MB for synchronous transactions and 12MB for asynchronous transactions.

  • The "Apex heap size too large" error occurs when too much data is being stored in memory during processing. The limit depends on the type of execution (E.g. synchronous vs asynchronous calls) and the current value can be found in the Apex Developer's Guide.

It is important to review your code and follow best practices to ensure that the heap limit does not exceed the maximum. The below example shows the incorrect use of collections. 

The List baseList, the value of SampleMap and the List tempList are pointing to the same memory address. As a result, the heap size doubles with each iteration of the loop.

public class HealsizeExample{

   public static void testHeapSize(){

       String str = 'aaaaa bbbbb ccccc ddddd eeeeee fffff hhhhh jjjjj kkkkk lllll mmmmm';

       List<String> baseList = str.split(' ');

       System.debug('This is baseList :'+baseList);

       System.debug('This is baseList :'+baseList.size());

       List<String> bigList = baseList;

       system.debug('This is bigList :'+bigList);

       System.debug('This is bigList :'+bigList.size());

       Map<integer, List<String>> SampleMap = new Map<integer, List<String>>();

       SampleMap.put(1, bigList);

       system.debug('This is SampleMap :'+SampleMap);

       System.debug('This is SampleMap :'+SampleMap.size());

       for (integer i=0; i<50; i++) {

           List<String> tempList = new List<String>();

           tempList = SampleMap.get(1);

           bigList.addAll(tempList);

       }

       system.debug('FINAL LIST SIZE IS '+bigList.size());

   }

}


Solution-

public class heapCheckSuccess{

 public static void myHeapTest(){

   String tStr = 'aaaaa bbbbb ccccc ddddd eeeeee fffff ggggg 11111 22222 33333 44444';

   List<String> baseList = tStr.split(' ');

   Map<integer, List<String>> Sample = new Map<integer, List<String>>();

   List<String> bigList = baseList;

 

   Sample.put(1, bigList);

   List<string> myList = new list<string>(); //Declare a new list

 

   for (integer i=0; i<50; i++) {

     List<String> tempList = new List<String>();

     tempList = Sample.get(1);

     system.debug('templist: ' + tempList.size());

     system.debug(' bigList: ' + bigList.size());

 

     myList.addall(tempList); //original code is  bigList.addall(tempList);

   }

 

   system.debug('FINAL LIST SIZE OF bigList IS '+ bigList.size());

   system.debug('myList IS '+mylist.size());

 }

}


Best Practices to avoid Heap Size

  1. Use the Transient Keyword

    • Try using the "Transient" keyword with variables in your controllers and extensions. The transient keyword is used to declare instance variables that cannot be saved, and shouldn't be transmitted as part of the view state for a Visualforce page.

  2. Use Limit Methods

  • Use heap limits methods in your Apex code to monitor/manage the heap during execution. 

  • Limits.getHeapSize() - Returns the approximate amount of memory (in bytes) that has been used for the heap in the current context.

  • Limits.getLimitHeapSize() - Returns the total amount of memory (in bytes) that can be used for the heap in the current context.

  1. Fetch only necessary Fields in the SOQL Query

    • If the objects in your collection contain related objects (i.e., Account objects with a number of related Contacts for each) make sure the related objects only contain the fields that are actually needed by your script.

  2. Use SOQL For Loops

    • To avoid heap size limits, developers should always use a SOQL "for" loop to process query results that return many records. SOQL "for" loops retrieve all sObjects in a query and process multiple batches of records through the use of internal calls to query and queryMore.

    • Issue

List accs = [SELECT Id, Name FROM Account];

for(Account a : accs){

  System.debug(a.Name);

}

List accs = [SELECT Id, Name FROM Account];

for(Account a : accs){

  System.debug(a.Name);

}

    • Solution

    • for(Account a : [SELECT Id, Name FROM Account]){

        System.debug(a.Name);

      }

      for(Account a : [SELECT Id, Name FROM Account]){

        System.debug(a.Name);

      }

  1. Switching to Batch Apex increased the heap limit to 12000000 bytes. Also, by setting the scope to 1 only one attachment was processed at a time.

  2. Don't use class-level variables to store a large amount of data.
  3. Run Future Methods with Higher Limits (Pilot)

@future(limits='2xHeap')

 

    public static void myFutureMethod() {

 

    // Your code here

 

    }

 

Tuesday, June 18, 2013

Factors that Affect Data Access In SFDC Integration

There are many factors that comes when we are doing some integration with another system.  When using the API, the following factors affect access to your organization’s data:
1. Access:  
     Your organization must be enabled for API access.
2. Choosing a WSDL: 
      Here are two Force.com Web services for which you can obtain WSDL files for API access:                                         
a)  Force.com EnterpriseWSDL
This API is for most enterprise users who are developing client applications for their organization. The enterprise WSDL file is a strongly typed representation of your organization’s data. Note the following when generating the enterprise WSDL:
1)   If new custom fields or objects are added to, renamed, or removed from your organization’s information, you need to re-generate the WSDL file in order to access them.
2) The generated WSDL contains the objects and fields in your organization, including those available in the selected versions of each installed package. If a field or object is added in a later package version, you must generate the enterprise WSDL with that package version to work with the object or field in your API integration.
b)  Force.com Partner WSDL—    
This API is for salesforce.com partners who are developing client applications for multiple organizations. As a loosely-typed representation of the Salesforce object model, the partner WSDL can be used to access data within any organization.
3. User Permissions: 
   A user attempting to access the API must have the permission “API Enabled” selected. It’s selected by default.
4. Object Properties: 
      To create an object with the create() call, the object's createable 
Attribute must be set to true. To determine what operations are allowed on a given object, your client application can invoke thedescribeSObjects() call on the object and inspect the properties in the DescribeSObjectResult.
5. Page Layouts and RecordType:
    Requirements defined in the Salesforce user interface for page layouts and record types are not enforced by the API:Page layouts can specify whether a given field is required, but the API does not enforce such layout-specific field restrictions or validations in create() and update() calls. It’s up to the client application to enforce any such constraints, if applicable.
    Record types can control which picklist values can be chosen in a given record and which page layouts users with different profiles can see. However, such rules that are configured and enforced in the user interface are not enforced in the API. For example, the API does not validate whether the value in a picklist field is allowed per any record type restrictions associated with the profile of the logged-in user. Similarly, the API does not prevent a client application from adding data to a particular field simply because that field does not appear in a layout associated with the profile of the logged-in user.
6. Object-Level and Field-Level Security:                                                                                                        The API respects object-level and field-level security configured in the user interface. You can access objects and fields only if the logged-in user's permissions and access settings allow such access. For example, fields that are not visible to a given user are not returned in a query() or describeSObjects() call. Similarly, read-only fields can't be updated.