salesforce零基础学习(一百二十一)Limitation篇之Heap Size Limitation
本篇参考:
https://help.salesforce.com/s/articleView?id=000384468&type=1
https://help.salesforce.com/s/articleView?id=000385712&type=1
此前讲过CPU limitation:salesforce零基础学习(一百零二)Limitation篇之 CPU Limit
本篇说一下项目中也经常用到的 heap size limitation以及best practice.
首先先说一下 salesforce中的 heap size简单概念, salesforce中的heap size和java中的heap size概念基本相同,当对象或者变量创建时,就会给分配内存,当运行时基于逻辑动态分配内存。salesforce限制同步最大的 apex heap size是6MB,异步的场景最多的是12MB. 当transaction执行时,太多数据存储在内存中的情况下,可能触发 The "Apex heap size too large" 的错误。
如果去调查某一个功能逻辑的heap size情况,可以通过以下的步骤来分析:
- 通过debug log查看当前的 heap size情况。
- 在debug log中通过HEAP_ALLOCATE来确定对象或者变量的分配内存的情况。
- 通过最后的Maximum heap size: 了解当前的执行的transaction所使用的heap size情况。
- 针对heap size limit拥有两个方法可以查询:
- Limits.getHeapSize():返回已用于堆的大致内存量(单位为:字节)。
- Limits.getLimitHeapSize(): 返回堆中还可以使用的大致的内存量(单位为:字节)
Best practice
1. 不使用class级别的变量去存储大量数据(也不一定局限于 class级别的变量,list尽量别存储大量数据)
错误案例: 下面的demo中: baseList,SampleMap的value以及tempt list都指向了同一个内存地址,执行以后,这个内存地址便会超限,从而触发The "Apex heap size too large" 的limitation
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,避免之前的内存倍速增长。
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());
2. 使用SOQL for loop从大量查询的数据中迭代和处理数据,官方也介绍了很多的 SOQL for loop的demo。详情可查看:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_loops_for_SOQL.htm
未改进前的简单的demo如下:
List<Account> accs = [SELECT Id, Name FROM Account LIMIT 50000];
针对 heap size修改的情况下,官方给出的建议,此种情况下,每200条执行一次数据,大量的减少了 heap size的使用。
SOQL for loop通过调用SOAP API的query和queryMore方法,使用高效的分块来检索所有sObjects(每次处理200条数据)。开发人员可以通过使用SOQL for loop处理返回多条记录的查询结果来避免堆大小的限制。
for(Account a : [SELECT Id, Name FROM Account LIMIT 50000]){
//TODO custom logic
}
当然,在多租户环境下,我们的limitation也不止 heap size,上述方法是否是最优解需要具体情况具体分析。当我们使用 SOQL for loop并且数据量大的情况下,这种方法可能会导致使用更多的CPU周期,逻辑执行时间也变得多了。除了官方上面的链接介绍以外,也可以看一下下面的邱老板的demo
https://blog.keal.us/salesforce/soql-for-loop%e7%9a%84%e6%95%88%e7%8e%87%e9%97%ae%e9%a2%98/
3. 变量使用 'transient'关键字,用于声明不需要被保存的变量,并且在VF page情况下也不会计入view state
4. 在运行时环境下,通过在迭代list / set / map时从集合中移除不必要的item来减小堆大小。
除此以外的几点优化点作为参考:
1. 避免使用无效的临时变量。比如代码中的临时变量后续没有调用,造成了额外的花销,这种没有用的代码尽量删除。
2. 更短的命名以及Field api 名称: 诚然使用好的命名规范有更强的可读性,不过短的名字确实可以省一些 heap size
移除不必要的debug log语句,特别是生产环境。
总结:heap size和CPU limitation的优化相辅相成,不要为了某一个优化而特意放弃另外一个,彼此形成一下平衡。篇中有错误地方欢迎指出,有不懂欢迎留言。
salesforce零基础学习(一百二十一)Limitation篇之Heap Size Limitation的更多相关文章
- salesforce 零基础学习(二十一)workflow Q&A
有一篇内容专门写了workflow,后来用到的时候心生疑问,不知道小伙伴有没有和我想法一样的,workflow具体内容原来已经说过,不在过多叙述,只说一下运行条件. 那就是:当满足运行条件时,执行相关 ...
- salesforce 零基础学习(二十二)Test简单使用
本篇内容只是本人简单的mark开发中常出现的一些疑问,方便后期项目使用时奠定基础,如果对Test零基础童鞋,欢迎查看Test官方的使用介绍: https://help.salesforce.com/a ...
- salesforce 零基础学习(二十)简单APP制作
本篇参考链接:https://developer.salesforce.com/trailhead/project/salesforce_developer_workshop 本篇讲述的是最简单的AP ...
- salesforce 零基础学习(六十一)apex:component简单使用以及图片轮转播放的实现
有的时候,我们项目有可能有类似需求:做一个简单的图像轮转播放功能,不同的VF页面调用可以显示不同的图片以及不同的图片描述.这种情况,如果在每个页面单独处理相关的图像轮转播放则显得代码特别冗余,此种情况 ...
- salesforce 零基础学习(四十一)Group
salesforce中,有的时候我们需要将一组用户放进一个Group,用来实现以下主要功能: 1.通过sharing rule设置默认的共享访问; 2.将记录分享给其他用户; 3.指定同步的联系人,这 ...
- salesforce 零基础学习(二十八)使用ajax方式实现联动
之前的一篇介绍过关于salesforce手动配置关联关系实现PickList的联动效果,但是现实的开发中,很多数据不是定死的,应该通过ajax来动态获取,本篇讲述通过JavaScript Remoti ...
- salesforce 零基础学习(二十四)解析csv格式内容
salesforce中支持对csv格式的内容批量导入,可以使用dataloader,然而有些情况下,当用户没有相关权限使用dataloader导入情况下,就的需要使用VF和apex代码来搞定. 基本想 ...
- salesforce 零基础学习(五十一)使用 Salesforce.com SOAP API 实现用户登录以及简单的增删改查(JAVA访问salesforce)
此篇请参看:https://resources.docs.salesforce.com/202/latest/en-us/sfdc/pdf/salesforce_developer_environme ...
- salesforce 零基础学习(三十一)关于LookUp字段点击Save时的Validation
今天在群里大概遇到了这样一个问题,明明这个User存在,但是save的时候提示信息说Value不存在,大概的意思如下图所示,目前认为这种问题常见的可能情况有两种. 一.此字段设置Validation ...
- salesforce 零基础学习(二十九)Record Types简单介绍
在项目中我们可能会遇见这种情况,不同的Profile拥有不同的页面,页面中的PickList标签可能显示不同的值.这个时候,使用Record Types可以很便捷的搞定需求. Record Types ...
随机推荐
- KingbaseES R6 集群修改物理IP和VIP案例
在用户的实际环境里,可能有时需要修改主机的IP,这就涉及到集群的配置修改.以下以例子的方式,介绍下KingbaseES R6集群如何修改IP. 一.案例测试环境 操作系统: [KINGBASE@nod ...
- C#,根据路径获取某个数字开头的所有文件夹,并获取最新文件夹进行替换文件
项目需求获取某路径下为1开头文件夹,并替换最新文件夹内容,话不多说,上代码 private void Form1_Load(object sender, EventArgs e) { try { st ...
- PLG SaaS 产品 Figma 商业模式拆解
9 月 15 日,Figma 的 CEO Dylan Field 发布消息:今天,Figma 宣布接受 Adobe 的收购... Adobe 以约 200 亿美元收购 Figma,这也是 Adobe ...
- 微信小程序-云函数、云存储
云函数是运行在服务器端的 创建一个目录cloud project.config.json配置云函数目录 cloud目录有个云朵.代表云函数 初始化成功了 新建一个云函数 cloud目录右击 新建一个N ...
- 单机部署minio,设置Nginx代理,配置https(TLS)访问
安装 下载地址:https://dl.min.io/ # 创建目录 mkdir -p /usr/local/minio/{data,bin,etc} # 下载minio wget https://dl ...
- Portainer 基本功能介紹之升級映像檔並更新 Container
文档地址:https://www.asustor.com/zh-tw/online/College_topic?topic=145#dpt7
- Gitlab基础知识介绍
GitLab架构图 Gitlab各组件作用 -Nginx:静态web服务器. -gitlab-shell:用于处理Git命令和修改authorized keys列表. -gitlab-workhors ...
- GitLab 之 Git LFS 大文件存储的配置
转载自:https://cloud.tencent.com/developer/article/1010589 1.Git LFS 介绍 Git 大文件存储(Large File Storage,简称 ...
- 20_IO
IO框架 一. 流的概念 概念:内存与存储设备之间传输数据的通道 水借助管道传输:数据借助流传输 二. 流的分类 按方向[重点] 输入流:将<存储设备>中的内容读入到<内存>中 ...
- NOIP2011 提高组 聪明的质监员(二分+前缀和)
看到这道题,应该都能想到用二分,那问题是怎么去判定呢? 我们考虑用前缀和(a1统计w,a2统计v),枚举每个矿石,,当前判定的值是x,如果该矿石的w>=x,a1[i]=a1[i-1]+1,a2[ ...