本篇参考:

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拥有两个方法可以查询:
    1. Limits.getHeapSize():返回已用于堆的大致内存量(单位为:字节)。
    2. 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

salesforce 零基础学习(四十二)简单文件上传下载

4. 在运行时环境下,通过在迭代list / set / map时从集合中移除不必要的item来减小堆大小。

除此以外的几点优化点作为参考:
1. 避免使用无效的临时变量。比如代码中的临时变量后续没有调用,造成了额外的花销,这种没有用的代码尽量删除。
2. 更短的命名以及Field api 名称: 诚然使用好的命名规范有更强的可读性,不过短的名字确实可以省一些 heap size
移除不必要的debug log语句,特别是生产环境。

总结:heap size和CPU limitation的优化相辅相成,不要为了某一个优化而特意放弃另外一个,彼此形成一下平衡。篇中有错误地方欢迎指出,有不懂欢迎留言。

salesforce零基础学习(一百二十一)Limitation篇之Heap Size Limitation的更多相关文章

  1. salesforce 零基础学习(二十一)workflow Q&A

    有一篇内容专门写了workflow,后来用到的时候心生疑问,不知道小伙伴有没有和我想法一样的,workflow具体内容原来已经说过,不在过多叙述,只说一下运行条件. 那就是:当满足运行条件时,执行相关 ...

  2. salesforce 零基础学习(二十二)Test简单使用

    本篇内容只是本人简单的mark开发中常出现的一些疑问,方便后期项目使用时奠定基础,如果对Test零基础童鞋,欢迎查看Test官方的使用介绍: https://help.salesforce.com/a ...

  3. salesforce 零基础学习(二十)简单APP制作

    本篇参考链接:https://developer.salesforce.com/trailhead/project/salesforce_developer_workshop 本篇讲述的是最简单的AP ...

  4. salesforce 零基础学习(六十一)apex:component简单使用以及图片轮转播放的实现

    有的时候,我们项目有可能有类似需求:做一个简单的图像轮转播放功能,不同的VF页面调用可以显示不同的图片以及不同的图片描述.这种情况,如果在每个页面单独处理相关的图像轮转播放则显得代码特别冗余,此种情况 ...

  5. salesforce 零基础学习(四十一)Group

    salesforce中,有的时候我们需要将一组用户放进一个Group,用来实现以下主要功能: 1.通过sharing rule设置默认的共享访问; 2.将记录分享给其他用户; 3.指定同步的联系人,这 ...

  6. salesforce 零基础学习(二十八)使用ajax方式实现联动

    之前的一篇介绍过关于salesforce手动配置关联关系实现PickList的联动效果,但是现实的开发中,很多数据不是定死的,应该通过ajax来动态获取,本篇讲述通过JavaScript Remoti ...

  7. salesforce 零基础学习(二十四)解析csv格式内容

    salesforce中支持对csv格式的内容批量导入,可以使用dataloader,然而有些情况下,当用户没有相关权限使用dataloader导入情况下,就的需要使用VF和apex代码来搞定. 基本想 ...

  8. salesforce 零基础学习(五十一)使用 Salesforce.com SOAP API 实现用户登录以及简单的增删改查(JAVA访问salesforce)

    此篇请参看:https://resources.docs.salesforce.com/202/latest/en-us/sfdc/pdf/salesforce_developer_environme ...

  9. salesforce 零基础学习(三十一)关于LookUp字段点击Save时的Validation

    今天在群里大概遇到了这样一个问题,明明这个User存在,但是save的时候提示信息说Value不存在,大概的意思如下图所示,目前认为这种问题常见的可能情况有两种. 一.此字段设置Validation ...

  10. salesforce 零基础学习(二十九)Record Types简单介绍

    在项目中我们可能会遇见这种情况,不同的Profile拥有不同的页面,页面中的PickList标签可能显示不同的值.这个时候,使用Record Types可以很便捷的搞定需求. Record Types ...

随机推荐

  1. 2021年3月-第02阶段-前端基础-Flex 伸缩布局-移动WEB开发_流式布局

    移动web开发流式布局 1.0 移动端基础 1.1 浏览器现状 PC端常见浏览器:360浏览器.谷歌浏览器.火狐浏览器.QQ浏览器.百度浏览器.搜狗浏览器.IE浏览器. 移动端常见浏览器:UC浏览器, ...

  2. Java SE 3、封装

    封装 封装的好处 隐藏实现细节 可以对数据进行验证,保证安全合理 实现步骤 将属性进行私有化private 提供一个公共的(public)set方法,用于对属性判断并赋值 public void se ...

  3. Ubuntu 系统服务器初始化配置、安全加固、内核优化和常用软件安装的Shell脚本分享

    转载自:https://www.bilibili.com/read/cv13875402?spm_id_from=333.999.0.0 描述: 适用于企业内部 Ubuntu 操作服务器初始化.系统安 ...

  4. k8s集群中安装rook-ceph

    容器的持久化存储 容器的持久化存储是保存容器存储状态的重要手段,存储插件会在容器里挂载一个基于网络或者其他机制的远程数据卷,使得在容器里创建的文件,实际上是保存在远程存储服务器上,或者以分布式的方式保 ...

  5. Winsw将jar包部署为windows服务

    1. 下载Winsw https://github.com/winsw/winsw/releases 下载winsw官网上的xml文件和.exe文件 2. 编辑配置文件 创建一个文件夹demo,将所需 ...

  6. kubernetes 查看pod 的容器日志

    1.pod若处于运行状态,则通过kubectl logs 即可 # 查看指定pod的日志 kubectl logs <pod_name> kubectl logs -f <pod_n ...

  7. ImGUI 1.87 绘制D3D外部菜单

    ImGUI 它是与平台无关的C++轻量级跨平台图形界面库,没有任何第三方依赖,可以将ImGUI的源码直接加到项目中使用,该框架通常会配合特定的D3Dx9等图形开发工具包一起使用,ImGUI常用来实现进 ...

  8. go使用JWT进行跨域认证最全教学

    JWT前言 JWT是JSON Web Token的缩写.JWT本身没有定义任何技术实现,它只是定义了一种基于Token的会话管理的规则,涵盖Token需要包含的标准内容和Token的生成过程. JWT ...

  9. MatrixOne从入门到实践01——初识MatrixOne

    初识MatrixOne 简介 MatrixOrigin 矩阵起源 是一家数据智能领域的创新企业,其愿景是成为数字世界的核心技术提供者. 物理世界的数字化和智能化无处不在.我们致力于建设开放的技术开源社 ...

  10. Java学习之路:流程控制

    2022-10-11 10:58:41 前言 本文开始流程控制方面的学习,主要包括用户交互和流程控制语句,适合新手学习. 1 用户交互Scanner 1.1 Scanner对象 Java提供了一个可以 ...