Oracle PL/SQL-检查内存泄漏?

Oracle PL/SQL-检查内存泄漏?,oracle,memory-leaks,plsql,Oracle,Memory Leaks,Plsql,我有一些PL/SQL代码,我认为可能有内存泄漏。每次我运行它时,它似乎比以前运行得越来越慢,即使现在我正在减小输入大小。我怀疑的代码是使用批量收集从游标填充数组,类似这样 open c_myCursor(in_key); fetch c_myCursor bulk collect into io_Array; /*io_array is a parameter, declared as in out nocopy */ close c_myCursor; 我不

我有一些PL/SQL代码,我认为可能有内存泄漏。每次我运行它时,它似乎比以前运行得越来越慢,即使现在我正在减小输入大小。我怀疑的代码是使用批量收集从游标填充数组,类似这样

    open c_myCursor(in_key);
         fetch c_myCursor bulk collect into io_Array; /*io_array is a parameter, declared as in out nocopy */
    close c_myCursor;
我不知道如何检查是什么导致了这种减速。我知道Oracle中有一些表可以跟踪这种内存使用情况,但我不确定是否有可能查看这些表并找到一些有用的方法来了解我的代码在做什么

另外,我尝试注销会话并在大约10-15分钟后重新登录,但仍然非常慢

Oracle版本是10.2


结果发现还有其他数据库活动。DBA决定在我开始更改和测试代码的同时运行一些大型插入和更新作业。我怀疑我的代码是根本原因,因为没有人告诉我其他作业正在运行(我只是在其他作业完全冻结了所有内容,所有其他开发人员都很恼火之后才听说这个作业)。这可能就是我的代码越来越慢的原因

是否有一种方法可以通过编程方式找到这一点,例如查询会话以插入/更新大量数据,以防DBA下次这样做时忘记告诉我?

介绍了DBMS\u PROFILER。我认为代码中最慢的部分可能与内存泄漏有关。无论如何,如果你回到原来的问题,它会越来越慢,那么首先要做的就是看看什么是慢的,然后假设内存泄漏

听起来好像在执行之间没有提交,重做日志越来越大。这可能是DB需要提供读取一致性的原因

您还可以检查企业管理控制台。你使用哪个版本?永远不要使用XE进行开发,因为据我所知,专业版本可以用于开发目的。企业管理控制台甚至会为您提供建议。也许它可以告诉您一些有关PLSQL问题的巧妙信息。

“我尝试注销会话并在大约10-15分钟后重新登录,但仍然非常缓慢。”

假设您在*nix平台上使用传统的专用连接,这几乎可以排除任何内存泄漏。当您建立到数据库的新连接时,oracle将为其派生一个新进程,所有PGA内存都将属于该进程,并且在会话断开且进程终止时,它将被释放(由操作系统释放)

如果您使用的是共享服务器连接,那么会话将使用属于进程和共享内存的内存。这可能更容易出现内存泄漏问题

Windows的工作方式并不完全相同,因为它不会为每个会话派生一个单独的进程,而是在单个Oracle进程下有一个单独的线程。同样,我怀疑这会更容易发生内存泄漏


我通常会首先查找其他问题,可能会从c_myCursor的查询开始。也许它必须读取更多的旧数据才能获得新数据?

如果查询返回的数据非常多,那么您收集的数据可能会非常大,比如10000条记录,这可能是可疑内存使用的原因

您可以通过记录批量收集到的集合的大小来检查这一点。如果较大的是10×000(只是粗略的估计,这取决于数据),你可以考虑分割和处理部分数据,SMTH如下:

declare
  cursor cCur is select smth from your_table;
  --
  type TCur is table of cCur%rowtype index by pls_integer;
  --
  fTbl TCur;
begin
  open cCur;
  loop
    fTbl.delete;
    fetch cCur bulk collect into fTbl limit 10000;
    exit when cCur%notfound;

    for i in 1 .. fTbl.count loop
      --do your wok here
    end loop;
  end loop;
  close cCur;
end;

既然你说那个表被声明为No.NoCopIt,我明白你不能直接改写这样的逻辑,但只需考虑方法论,也许这可以帮助你。

V$sEsStices是一种快速查看每个会话使用什么资源的方法——CPU、物理读、逻辑读、PGAI内存,等等。

PL/SQL甚至容易受到内存泄漏的影响吗?SQL是一种非常高级的语言,这些语言通常不会有这个问题。所讨论的代码不做任何提交,但也不做任何插入。没有更新,没有删除。调用可疑代码的PL/SQL脚本没有提交。我没有使用XE。我得看一下档案器。我们的IDE是PL/SQL开发人员(Allround Automation),我认为它可以自动对脚本和它们调用的代码进行评测,但我不确定它是否评测了我需要的内容。我必须研究它…哦,是的,我怀疑这段代码是因为它是更改包中的一些新东西之一,但它是唯一执行任何数据检索的代码,也是唯一填充数组的代码。工作站是Windows,服务器是unix(不确定是哪种风格)。我不知道它们是共享连接还是专用连接。
c_myCursor
正在查看的数据是非常静态的,只有当我们从DBA请求时才从主服务器刷新,而且已经有一段时间没有了。有趣的是。。。是否有办法查看会话正在使用的对象?在本例中,问题是另一个进程正在更新一个表。我想如果是另一张桌子,我就不会有这样的问题。是否有其他视图加入此视图以查看相关对象?或者,即使我能看到正在执行的语句,这可能就足够了。选择v$sessmetric.*、sql\u text、sql\u fulltext from v$sessmetric left outer join(选择*from v$sql,其中用户执行>0)查询运行在v$sessmetric.session\u id=查询运行。解析\u schema\u id;