※この記事は英語版を翻訳しており、一部に機械翻訳を含むため内容は後日更新される可能性があります。最新の内容は英語版を参照してください。表示言語は画面右下の言語名から切り替えられます。
Salesforce(セールスフォース)で「Apexヒープサイズが大きすぎます」エラーは、メモリ使用量が制限を超えた場合に発生します。同期トランザクション(Transaction)では6MB、非同期トランザクションでは12MBの制限があります。現在の値は Apex 開発者ガイド に記載されています。コードの最適化とベストプラクティスの遵守が必要です。具体的には、クラスレベルの変数を避け、SOQL Forループを利用し、不要な変数を早期に解放することが推奨されます。
ヒープ(heap)制限を超える Apex (エイペックス)コードの例を次に示します。
@isTest
private class heapCheckIssue{
static testMethod void myTest(){
String tStr = 'aaaaa bbbbb ccccc ddddd eeeeee fffff ggggg 11111 22222 33333 44444';
List<String> baseList = tStr.split(' ');
List<String> bigList = baseList;
Map<integer, List<String>> SampleMap = new Map<integer, List<String>>();
SampleMap.put(1, bigList);
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());
}
}
この例は、コレクションの誤った使用を示しています。
List baseList、SampleMap の値、および List tempList が同じメモリアドレスを参照しています。その結果、ヒープサイズはループの反復ごとに 2 倍になります。
次の例は、ヒープサイズを超えない同様のアルゴリズムを示しています。
@isTest
private class heapCheckSuccess{
static testMethod void myTest(){
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());
}
}
上記の例では、bigList 変数を使用する代わりに、新しい List を使用して各反復で tempList の値を格納してからリストを追加しているため、ヒープサイズが大きくなりすぎることはありません。
以下のサンプルでは、50000 個の項目を処理できますが、最大のヒープには検索語、クエリ、200 件の取引先のリスト、および結果のリストが含まれます。これは、処理されているすべての範囲では比較的少ない量です。
public with sharing class myClass{
private String myString;
public myClass(String searchString) {
myString = searchString;
}
private string getQueryString() {
return 'SELECT Id, Name FROM Account LIMIT 50000';
}
public List<Account> getSearchResults() {
List<Account> searchResults = new List<Account>();
for(List<Account> accts : Database.Query(getQueryString())) {
// Each loop processes 200 items
for(Account a : accts) {
if (a.Name != null && a.Name.contains(myString)) {
searchResults.add(a);
}
}
}
return searchResults;
}
}
このトピックについての詳細は、SOQL For ループに関するドキュメントを確認してください。
000384468

We use three kinds of cookies on our websites: required, functional, and advertising. You can choose whether functional and advertising cookies apply. Click on the different cookie categories to find out more about each category and to change the default settings.
Privacy Statement
Required cookies are necessary for basic website functionality. Some examples include: session cookies needed to transmit the website, authentication cookies, and security cookies.
Functional cookies enhance functions, performance, and services on the website. Some examples include: cookies used to analyze site traffic, cookies used for market research, and cookies used to display advertising that is not directed to a particular individual.
Advertising cookies track activity across websites in order to understand a viewer’s interests, and direct them specific marketing. Some examples include: cookies used for remarketing, or interest-based advertising.