function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
RajivRajiv 

Query of LOB fields Exception heap usage to exceed limit

Hi 

 

I have written one trigger on Feedcomment. It's working fine on sandbox but when we move into the production

some new exception is coming i.e.

System.LimitException:Query of LOB fields caused heap usage to exceed limit.

 

The error is coming on this SOQL query:

 List<UserFeed> usefd = [SELECT Id, Type, body, ContentFileName, createdbyId, InsertedById, ParentId, Body, Title, ContentData,     FeedItemId,(SELECT CommentBody, InsertedById, FeedItemId FROM FeedComments ) from UserFeed where CreatedById =: feedcommentid ORDER BY  CreatedDate ];

 

Does any one know what type of error is this.

 

Thanks,

Rajiv

 


Best Answer chosen by Admin (Salesforce Developers) 
jhartjhart

Just got the official word from salesforce.

 

The heap size changes in Winter '12 are being rolled back tonight.  This means two things:


(a) heap size limits will be returning to the old 3/6 limits

and

(b) heap calculation will *also* be returning to the old method of one-object-at-a-time within the SOQL for loop instead of all-objects-at-once.

All Answers

bob_buzzardbob_buzzard

This sounds like you are pulling back more information that can be stored in the available heap space, which is 3Mb.   I'd imagine its because you are retrieving the ContentData field, which returns the base 64 encoded contents of a file.

AmyJonesAmyJones

Same issue we are identifying with our existing applications now. Is this because of new winter release done by Salesforce???

 

 

vijaymindvijaymind

No , I tried to find out in Winter 12 Release and not documented anywhere that Heap Size Reduced 3 MB as earlier it was 6 MB.  Now documented is something like this.

Higher Governor Limits in Some CategoriesThe following governor limits are higher for Batch Apex and future

• Total number of SOQL queries issued is 200 instead of 100.

•Total number of executed code statements is 1,000,000 instead oIn addition, the heap size limit is now doubled and is raised for Batch Apex  And Future Methods .

•Total heap size is 6 MB.

•Total heap size for Batch Apex and future methods is 12 MB.

 

 

 

I am also fed up the running code is **bleep**ed up.

 

 

jhartjhart

This is a regression in Winter '12.

 

It used to be the case that heap was only allocated / counted when you pulled an object off its [select] statement, so you could easily do this:

 

 

// Works fine pre-Winter '12 b/c only one Attachment Body was allocated at once
// Fails in Winter '12 because all Attachments are allocated up front
for (Attachment i : [select Body, BodyLength from Attachment where ...]) System.debug(i.BodyLength);


Then you are OK as long as you don't leave the Body on your heap across iterations - in other words, the above code works great in all prior releases.

However, in Winter '12, the entire result set is counted against your heap right away, so the query itself blows the heap.

 

 

That means the only way to query against multiple Attachments - even if you have a good strategy for disposing of them within your SOQL loop - is to use row-at-a-time selects.

 

Can someone at Salesforce verify this change is intended, and we should all alter our code accordingly?

 

 

Note - this might actually be intended.  If SFDC's appservers do, in fact, pull all the bits from the DB in one shot, and as a result were blowing their own heaps due to our Apex code, then I could understand that they might have to change the point of calculation to push the problem into our laps.  But row-at-a-time selects aren't great either; the better solution would be to make the appserver behavior match the old calculation behavior...

 

Salesforce support, I have opened case 06429984 to track this issue.

jhartjhart

A couple things:

 

a.  I'm on the phone with salesforce partner support, and they inform me that the heap size limits in the Winter '12 documentation is wrong, and is actually still at the old limits (3 inline, 6 for future & batch).  I don't know whom to believe, however.

 

b.  Just got an email from a PM at salesforce, saying that the heap size changes are being rolled back tonight.   I think that means that the heap size limits WILL be returning to the old 3/6 limits, but the heap calculation will *also* be returning to the old method of one-object-at-a-time within the SOQL for loop instead of all-objects-at-once.

 

c.  Here's how to reproduce:

 

Contact c = new Contact(LastName = 'test');
insert c;

// build a 2MB attachment string
string s = '1';
while (s.length() < Math.pow(2,21)) s = s + s;
Blob b = Blob.valueOf(s);

insert new Attachment[] {
	 new Attachment(Body = b, ParentId = c.Id, ContentType = 'text/plain', Name = 'sample1.txt')
	,new Attachment(Body = b, ParentId = c.Id, ContentType = 'text/plain', Name = 'sample2.txt')
	,new Attachment(Body = b, ParentId = c.Id, ContentType = 'text/plain', Name = 'sample3.txt')
	,new Attachment(Body = b, ParentId = c.Id, ContentType = 'text/plain', Name = 'sample4.txt')
	};

System.debug(c.Id);

 

Take note of the contact ID so printed, and then run this code:

 

Id c = '<INSERT YOUR CONTACT ID HERE>';

System.debug('heap size is ' + Limits.getHeapSize() + ' out of ' + Limits.getLimitHeapSize());

for (Attachment i : [select BodyLength from Attachment where ParentId = :c]) System.debug(i);

System.debug('heap size is ' + Limits.getHeapSize() + ' out of ' + Limits.getLimitHeapSize());

// this used to work pre-Winter '12
for (Attachment i : [select Body, BodyLength from Attachment where ParentId = :c]) System.debug(i);


jhartjhart

Just got the official word from salesforce.

 

The heap size changes in Winter '12 are being rolled back tonight.  This means two things:


(a) heap size limits will be returning to the old 3/6 limits

and

(b) heap calculation will *also* be returning to the old method of one-object-at-a-time within the SOQL for loop instead of all-objects-at-once.

This was selected as the best answer
vijaymindvijaymind

What is mean 3/6 Limit.

 

3 MB Total heap size is ? And 

6 MB Total heap size for Batch Apex and future methods  ?

 

?????

 

ANd what They Rolled backed as I had mentioned in my Above Post.

New Limits are .

•Total heap size for Batch Apex and future methods is 12 MB.

Higher Governor Limits in Some CategoriesThe following governor limits are higher for Batch Apex and future

• Total number of SOQL queries issued is 200 instead of 100.

•Total number of executed code statements is 1,000,000 instead oIn addition, the heap size limit is now doubled and is raised for Batch Apex  And Future Methods .

•Total heap size is 6 MB.

•Total heap size for Batch Apex and future methods is 12 MB.

 

And what was the problem in this release by reason they rolled backed ????

 

 

jhartjhart

Yes, by "3/6" I meant 3 for normal apex, 6 for batch & future.  I don't know if they rolled back any other limits.

 

I imagine the problem that I pointed out (counting all objects in a SOQL for loop against the heap up front, instead of one-at-a-time in the body of the loop), may be part of the reason for rollback.  That broke a lot of code that used to work.

 

 

I confirmed the rollback has occurred and SOQL for loops are working again:

 

Id c = 'CONTACT ID FROM PREVIOUS APEX CHUNK';

System.debug('pre loop:' + Limits.getHeapSize() + '/' + Limits.getLimitHeapSize());

// this works again after the rollback:
for (Attachment i : [select Body, BodyLength from Attachment where ParentId = :c]) {
  System.debug('in loop: ' + Limits.getHeapSize() + '/' + Limits.getLimitHeapSize() + '     (bodylength is ' + i.BodyLength + ')');
  }

System.debug('post loop: ' + Limits.getHeapSize() + '/' + Limits.getLimitHeapSize());

 

Outputs:

 

pre loop:18/3000000
in loop: 2097224/3000000     (bodylength is 2097152)
in loop: 2097224/3000000     (bodylength is 2097152)
in loop: 2097224/3000000     (bodylength is 2097152)
in loop: 2097224/3000000     (bodylength is 2097152)
post loop: 2097224/3000000

 

Whereas before it would throw the exception immediately after the "pre loop" debug line.  Note that final "post loop" heap is still large, but (I suspect) it's only because the dead Attachment reference hasn't been garbage collected yet.

 

vijaymindvijaymind

Thanks jhart,

 

I got your point. Thank you very much again.