0

I have a visualforce page which is throwing me the error "Apex heap size too large: 6125236" I have referred to couple of similar issues here on stackexchange but this seems to be a different issue. Please find the Code below

global without sharing class AccountCntl {

    public Account CustUser {get; set; }
    public String jsonString {get; set; } 
    //public list<String> countryList {get; set; }
    public list<AccUtil.DropItem> countriesList {get; set; }  

    public AccountCntl (ApexPages.StandardController stdController) {

        /*this.CustUser = new Account();
        //this.countryList = new list<String>();
        this.countriesList = new list<AccUtil.DropItem>();
        String strId = ApexPages.currentPage().getParameters().get('id');
        System.debug('MY REC ID ' + strId);
        if(strId != null && strId != '') {
            this.CustUser = [select Id, Name, Level__c, Location_New__c, User_ID__c from Account where Id=:strId];
        }

        if(this.CustUser.Id==null && Userinfo.getUserType().contains('Partner')){
            // Set the CustUser based on the currently logged in user
            this.CustUser = [select contact.account.id from user where Id = :Userinfo.getUserId() limit 1].contact.account;
            this.CustUser = [select Id, Name, Level__c, Location_New__c, User_ID__c from Account where Id=:this.CustUser.Id];
        }

        if(this.CustUser != null && this.CustUser.Id != null){
            // Get list of Countries      
            countriesList = AccUtil.getCountryList(this.CustUser.Id);
            system.debug('Countries List = '+countriesList); 
            //countriesList.sort();
            /*set<String> dmySet = new set<String>();
            set<String> tmpdmySet = new set<String>();
            if(this.CustUser.Location_New__c != null) { 
                this.countryList.add(this.CustUser.Location_New__c);
                dmySet.add(this.CustUser.Location_New__c);
                tmpdmySet.add(this.CustUser.Location_New__c);
            }
            list<Sponsor__c> sponsors = [select Id, Location__c, Location__r.Domestic_Country__c from NewUser__c where CustUser__c=: this.CustUser.Id order BY Location__c];
            for(integer scnt=0; scnt<sponsors.size(); scnt++) {
                if(sponsors[scnt].Location__c != null && sponsors[scnt].Location__r.Domestic_Country__c != null) {
                    dmySet.add(sponsors[scnt].Location__r.Domestic_Country__c);
                }
            }

            list<Location__c> locList = [select Id, Domestic_Country__c, Domestic_Country__c from Location__c where Domestic_Country__c IN :dmySet
                                         order by Domestic_Country__c];
            for(integer scnt=0; scnt<locList.size(); scnt++) {
                if(locList[scnt].Domestic_Country__c != null) {
                    if(!tmpdmySet.contains(locList[scnt].Domestic_Country__c)) {
                        this.countryList.add(locList[scnt].Domestic_Country__c);
                        tmpdmySet.add(locList[scnt].Domestic_Country__c);
                    }
                }
            }
            *
                System.debug('COUNTRY LIST = ' + this.countriesList);
            // Get Downline CustUsers till 2 levels.
            this.jsonString = initializeJSONObject(this.CustUser, this.CustUser.Location_New__c);
            System.debug('JSON STRING = ' + this.jsonString);
        }
        else {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.WARNING,'You are not Paid CustUser and did not provided valid CustUser for Downline Map'));
        }   
    }

    public static String initializeJSONObject(Account acc, String country) {

        map<Id, list<Account>> SeniorobjMap = new map<Id, list<Account>>();
        Integer TOTAL_MAX_COUNT = 10000;
        Integer QUERY_ROWS_COUNT = 0;

        // Start Case 10632050
        Set<String> sponsorIds = new Set<String>();
        sponsorIds.add(acc.User_ID__c);
        // END Case 10632050

        // Get locations - this is more efficient that filtering on Sponsor.Location_New__c    
        List<Location__c> locs = [SELECT Id, Domestic_Country__c FROM Location__c WHERE Domestic_Country__c=:country];
        Set<Location__c> locSet = new Set<Location__c>();
        Set<Location__c> locExtendedSet = new Set<Location__c>();
        Set<String> locCntSet = new Set<String>();
        for (Location__c l : locs){
            locSet.add(l);
            locExtendedSet.add(l);
            if(l.Domestic_Country__c != null) locCntSet.add(l.Domestic_Country__c);
        }
        List<Location__c> newlocs = [SELECT Id, Domestic_Country__c FROM Location__c WHERE Domestic_Country__c IN :locCntSet];
        for (Location__c l : newlocs){
            locExtendedSet.add(l);
        }



        // Generating JSON Object / String
        JSONGenerator gen = JSON.createGenerator(true);
        gen.writeStartObject();
        gen.writeStringField('name', acc.Name);
        gen.writeStringField('accid', acc.Id);
        if(acc.Level__c != null) {
            gen.writeStringField('level', acc.Level__c);
        } 
        // Level 1 Juniors
        if(SeniorobjMap.containsKey(acc.Id)) {
            list<Account> level1List = SeniorobjMap.get(acc.Id);
            if (level1List.size() > 0){
                level1List.sort();
            }
            gen.writeFieldName('junior');
            gen.writeStartArray();
            for(integer cnt1=0; cnt1<level1List.size(); cnt1++) {
                gen.writeStartObject();
                gen.writeStringField('name', level1List[cnt1].Name);
                gen.writeStringField('accid', level1List[cnt1].Id);
                if(level1List[cnt1].Level__c != null) { gen.writeStringField('level', level1List[cnt1].Level__c); }

                // Level 2 Juniors
                if(SeniorobjMap.containsKey(level1List[cnt1].Id)) {
                    gen.writeFieldName('junior');
                    gen.writeStartArray();
                    list<Account> List = SeniorobjMap.get(level1List[cnt1].Id);
                    if (List.size()>0){
                        List.sort();
                    }
                    for(integer cnt2=0; cnt2<List.size(); cnt2++) {
                        gen.writeStartObject();
                        gen.writeStringField('name', List[cnt2].Name);
                        gen.writeStringField('accid', List[cnt2].Id);
                        if(level1List[cnt1].Level__c != null) { gen.writeStringField('level', level1List[cnt1].Level__c); }
                        gen.writeEndObject();
                    }
                    gen.writeEndArray();
                }
                // End Of Level 2 Juniors
                gen.writeEndObject();
            }
            gen.writeEndArray();
        }
        // End Of Level 1 Juniors

        gen.writeEndObject();
        // End of Main Object

        return gen.getAsString();            
    }

    //@Remote Action from javascript and return Json.. junior and grand junior
    @RemoteAction
    global static string getChildGrandchild(String DistId, String country){ 
        Account acc = [select Id, Name, Level__c, User_ID__c from Account where Id=:UserCustID];
        String strJSON = initializeJSONObject(acc, country);
        return strJSON;
    }


    //@Remote Action to send details for Portal User / Paid CustUser
    @RemoteAction
    global static string getPaidDistDetails(String UserCustID, String country){ 
        set<string> domesticCountries = AccUtil.getDomesticCountries(country);
        Account acc = [select Id, Name, Level__c, CustUser_Id_Format__c, Phone_1__c, Email__c, Close_to_Move_Up__c 
                       from Account where Id=:UserCustID limit 1];
        list<User> ussList = [Select Id, FullPhotoURL From User Where Contact.AccountId =:acc.Id limit 1];

        JSONGenerator gen = JSON.createGenerator(true);
        gen.writeStartObject();
        //gen.writeStringField('id', acc.Id);
        gen.writeStringField('name', acc.Name);
        gen.writeStringField('accid', acc.Id);
        if(acc.CustUser_Id_Format__c != null) { gen.writeStringField('UserCustID', acc.CustUser_Id_Format__c); }
        if(spnsr.size() > 0 && spnsr[0].Level__c != null) { gen.writeStringField('level', spnsr[0].Level__c); }

        User usr = [select Contact.AccountId from User where Id = :Userinfo.getUserId() limit 1];

        if(acc.Phone_1__c != null) { gen.writeStringField('phone', acc.Phone_1__c); }
        if(acc.Email__c != null) { gen.writeStringField('email', acc.Email__c); }
    }
    //@Remote Action to Send Search Result.
    @RemoteAction
    global static string performSearch(String fName, String lName, String UserCustID, String country) {
        list<Account> results;
        String searchResult = '';

        if(UserCustID != null && UserCustID != '') {
            results = [select id, Name from Account where User_ID__c=:UserCustID and CustUser_Status__c IN ('Active','Suspended','Restricted','Pending')];
            searchResult = generateSearchResult(results);
        }

        if(fName != null && fName != '' && lName != null && lName != '') {
            //results = [select id, Name from Account where Primary_First_Name__c=:fName and Primary_Last_Name__c=:lName ];
            String nameString = lName + ', ' + fName;
            String query = 'select id, Name from Account where Primary_First_Name__c ';

            if(fName.length() >= 4){
                fName = fName+'%';
                query += 'LIKE :fName AND '; 
            }else{
                query += ' = :fName AND ';
            }

            if(lName.length() >= 4){
                lName = lName+'%';
                query += 'Primary_Last_Name__c LIKE :lName AND '; 
            }else{
                query += 'Primary_Last_Name__c = :lName AND ';
            }

            query += 'CustUser_Status__c IN (\'Active\',\'Suspended\',\'Restricted\',\'Pending\')';

            //results = [select id, Name from Account where Primary_First_Name__c LIKE :fName and Primary_Last_Name__c LIKE :lName and CustUser_Status__c IN ('Active','Suspended','Restricted','Pending')];
            results = Database.query(query);
            searchResult = generateSearchResult(results);
        }
        System.debug(searchResult);
        return searchResult;
    }

    public static String generateSearchResult(list<Account> results) {
        String searchResult = '';    
        if(results != null && results.size() > 0) {


            JSONGenerator gen = JSON.createGenerator(true);
            gen.writeStartObject();
            gen.writeFieldName('results');
            gen.writeStartArray();
            for(integer i=0; i<results.size(); i++) {
                gen.writeStartObject();
                gen.writeStringField('accid', results[i].Id);
                gen.writeEndObject();
            }
            gen.writeEndArray();
            gen.writeEndObject();      
            searchResult = gen.getAsString();


        }
        else {
            searchResult = Label.PD_Downline_No_Search_Results;
        }
        return searchResult;
    }

    //@Remote Action to send complete hierarchy.
    @RemoteAction
    global static string getCompleteHierarchy(String accId, String country, String pdDistAccId) {
        set<String> dlsponsors = new set<String>();
        boolean isInHierarchy = false;
        JSONGenerator gen = JSON.createGenerator(true);
        String fullPath = '';
        gen.writeStartObject();
        gen.writeStringField('target', accId);
        Account acc1 = [Select Name from Account where Id = :accId];
        gen.writeStringField('Name', acc1.Name);
        gen.writeFieldName('treePath');
        gen.writeStartArray();
        // add target node to tree path
        gen.writeStartObject();
        gen.writeStringField('accid', accId);
        gen.writeEndObject();
        dlsponsors.add(accId);

        for(integer i=0; i<20; i++) {
            // Get upline sponsor with matching country
            list<NewUser__c> ulSponsors = [select Id, Sponsor_CustUser__c from NewUser__c where CustUser__c IN :dlsponsors and Location_New__c =:country limit 1];
            dlsponsors.clear();
            if(ulSponsors != null && ulSponsors.size() > 0 && ulSponsors[0].Sponsor_CustUser__c != null) {
                // Add Sponsor in set to traverse up in next loop
                dlsponsors.add(ulSponsors[0].Sponsor_CustUser__c);

                // Add Sponsor in the JSON object
                gen.writeStartObject();
                gen.writeStringField('accid', ulSponsors[0].Sponsor_CustUser__c);
                gen.writeEndObject();
                if(ulSponsors[0].Sponsor_CustUser__c == pdDistAccId) {
                    // If we meet at the top, then stop traversing up and send the result.
                    isInHierarchy = true;
                    gen.writeEndArray();
                    gen.writeEndObject();
                    break;
                }
            } else {
                break;
            }
        }

        if(isInHierarchy == true) {
            return gen.getAsString();
        }

        return 'NOT IN HIERARCHY';*/
    }
}

As you can see in the above code, we have complete code under comments. I cannot understand how this is hitting the heap limit. Can anyone debug this and help me resolve this issue.

Thanks

  • 1
    To be honest there are 300 lines of code, with lot of things commented, and it is not clear which code is actually executed to give an error. Can you trim your code to include minimal part of it which are required to reproduce an issue without commented lines? – kurunve Feb 8 at 8:15
  • Actually, except for the variable declaration, all the code is under comments. I am wondering how this code is hitting heap limit. There are remote actions in the code, but they are also under comments. – Sastri Feb 8 at 8:19
  • 1
    comment jsonString and try – Pranay Jaiswal Feb 8 at 14:51
  • 1
    You may want to make your limit from 10000 to something much smaller. 10,000 rows is impractical as is. – sfdcfox Feb 8 at 16:30
  • Thanks @Sfdcfox...limiting the MAX size worked but it is only displaying limited number of users. There are lot of users that has to display in the page. I have put limit.getheapsize>list condition and it will display the reduced the limit as 5000. Is there any other alternative to display all users? – Sastri Feb 16 at 12:59

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.