标签: reference-counting

如何在PHP中修复内存泄漏

我的PHP应用程序有一个可以导入记录的导入脚本.

目前,它是从CSV文件导入的.它正在读取CSV文件的每一行,使用fgetcsv一次一行,并且对于每一行,它在该记录上进行大量处理,包括数据库查询,然后继续下一行.它不应该继续累积更多的内存.

在导入大约2500条记录之后,PHP死了,说它已超过其内存限制(132 MB左右).

CSV文件本身只有几个megs - 发生的其他处理会进行大量的字符串比较,差异等.我有大量的代码在运行它并且很难想出一个'最小的再现样品'.

找到并解决这个问题有哪些好方法?

发现问题的原因

我有一个调试类,它在运行时记录我的所有数据库查询.因此,那些长约30KB的SQL字符串留在内存中.我意识到这不适合设计为长时间运行的脚本.

可能还有其他内存泄漏源,但我很确定这是我的问题的原因.

php memory-leaks reference-counting

17
推荐指数
2
解决办法
2万
查看次数

是否可以拦截(或意识到)COM引用计数暴露给COM的CLR对象

我已经改写了这个问题.

当.net对象通过COM iterop公开给COM客户端时,会创建一个CCW(COM Callable Wrapper),它位于COM客户端和Managed .net对象之间.

在COM世界中,对象保留其他对象对其的引用数量的计数.当引用计数变为零时,将删除/释放/收集对象.这意味着COM对象终止是确定性的(我们在.net中使用Using/IDispose用于确定性终止,对象终结器是非确定性的).

每个CCW都是一个COM对象,它的引用计数与任何其他COM对象一样.当CCW死亡(引用计数变为零)时,GC将无法找到CCW包装的CLR对象,并且CLR对象有资格进行收集.快乐的日子,一切都与世隔绝.

我想要做的是在CCW死时(即当它的引用计数变为零时)捕获,并以某种方式将此信号通知给CLR对象(例如,通过在被管理对象上调用Dispose方法).

那么,是否可以知道CLR类的COM可调用包装器的引用计数何时变为零?
和/或
是否可以在.net中为CCW提供AddRef和ReleaseRef的实现?

如果不是替代方法是在ATL中实现这些DLL(我不需要任何ATL帮助,谢谢).它不是火箭科学,但我不愿意这样做,因为我是内部唯一的开发人员,任何现实世界的C++或任何ATL.

背景
我在.net中重写了一些旧的VB6 ActiveX DLL(确切地说是C#,但这更像是.net/COM互操作问题,而不是C#问题).一些旧的VB6对象依赖于引用计数来在对象终止时执行操作(参见上面引用计数的解释).这些DLL不包含重要的业务逻辑,它们是我们为使用VBScript与我们集成的客户提供的实用程序和帮助程序函数.

我不想做什么

  • 引用计数.net对象而不是使用垃圾收集器.我对GC很满意,我的问题不在于GC.
  • 使用对象终结器.终结器是非确定性的,在这种情况下我需要确定性终止(如.net中的Using/IDispose惯用法)
  • 在非托管C++中实现IUnknown
    如果我要使用C++路由,我将使用ATL,谢谢.
  • 使用Vb6解决此问题,或重新使用VB6对象.本练习的重点是消除我们对Vb6的构建依赖.

谢谢
BW

接受的答案
分毫不差一千感谢史蒂夫·施泰纳,谁,唯一的(可能是可行的)想出了基于.NET的答案,埃里克,谁用一个非常简单的解决方案ATL上来.

然而,接受的答案是Bigtoe,他建议将.net对象包装在VbScript对象中(我认为不诚实),有效地为VbScript问题提供了一个简单的VbScript解决方案.

谢谢大家.

.net c# reference-counting com-interop

17
推荐指数
2
解决办法
5130
查看次数

动态数组是否超出范围时会自动解除分配?

在这个例子中

procedure foobar;
var tab:array of integer;
begin
  setlength(tab,10);
end;
Run Code Online (Sandbox Code Playgroud)

是阵列被破坏还是内存泄漏?

delphi memory-leaks reference-counting dynamic-arrays

16
推荐指数
1
解决办法
1万
查看次数

为什么这个字符串的引用计数为4?(德尔福2007)

这是一个非常特殊的Delphi问题(甚至可能是Delphi 2007特有的).我目前正在为实习字符串编写一个简单的StringPool类.作为一个优秀的小编码器,我还添加了单元测试,发现了令我困惑的东西.

这是实习的代码:

function TStringPool.Intern(const _s: string): string;
var
  Idx: Integer;
begin
  if FList.Find(_s, Idx) then
    Result := FList[Idx]
  else begin
    Result := _s;
    if FMakeStringsUnique then
      UniqueString(Result);
    FList.Add(Result);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

没有什么真正的花哨:FList是一个排序的TStringList,所以所有的代码都在查找列表中的字符串,如果它已经在那里它返回现有的字符串.如果它尚未出现在列表中,它将首先调用UniqueString以确保引用计数为1,然后将其添加到列表中.(我检查了结果的引用计数,并且在'hallo'被添加两次之后它是3,如预期的那样.)

现在来测试代码:

procedure TestStringPool.TestUnique;
var
  s1: string;
  s2: string;
begin
  s1 := FPool.Intern('hallo');
  CheckEquals(2, GetStringReferenceCount(s1));
  s2 := s1;
  CheckEquals(3, GetStringReferenceCount(s1));
  CheckEquals(3, GetStringReferenceCount(s2));
  UniqueString(s2);
  CheckEquals(1, GetStringReferenceCount(s2));
  s2 := FPool.Intern(s2);
  CheckEquals(Integer(Pointer(s1)), Integer(Pointer(s2)));
  CheckEquals(3, GetStringReferenceCount(s2));
end;
Run Code Online (Sandbox Code Playgroud)

这会将字符串'hallo'添加到字符串池两次并检查字符串的引用计数,并且s1和s2确实指向相同的字符串描述符.

每个CheckEquals都按预期工作,但最后一个.它失败,错误"预期:<3>但是:<4>".

那么,为什么引用计数为4?我原以为3:

  • S1
  • S2
  • 和StringList中的另一个

这是Delphi 2007,因此字符串是AnsiStrings.

哦,是的,函数StringReferenceCount实现为:

function GetStringReferenceCount(const _s: AnsiString): integer;
var
  ptr: …
Run Code Online (Sandbox Code Playgroud)

delphi string reference-counting delphi-2007 string-interning

16
推荐指数
1
解决办法
1302
查看次数

是否存在像TInterfacedObject这样的非引用计数基类?

我需要一个基类,TInterfacedObject但没有引用计数(所以一种TNonRefCountedInterfacedObject).

这实际上是第n次我需要这样一个课程,不知何故,我总是一次又一次地写作(阅读:复制和粘贴)我自己.我无法相信我没有可以使用的"官方"基类.

在RTL实现的某个地方是否存在基类,IInterface但没有引用计数,我可以从中派生我的类?

delphi interface reference-counting delphi-xe

16
推荐指数
1
解决办法
1864
查看次数

循环引用有哪些解决方案?

使用引用计数时,有哪些可能的解决方案/技术来处理循环引用?

最着名的解决方案是使用弱引用,但是关于该主题的许多文章暗示也存在其他方法,但是不断重复弱引用示例.这让我想知道,这些其他方法是什么?

  • 我不是问什么是引用计数的替代方法,而是使用引用计数时循环引用的解决方案是什么.

  • 这个问题不是关于任何具体问题/实施/语言而是一般性问题.

reference-counting circular-reference

15
推荐指数
2
解决办法
8705
查看次数

Delphi接口参考计数

我今天在测试时遇到了一个奇怪的情况.

我有很多接口和对象.代码如下所示:

IInterfaceZ = interface(IInterface)
['{DA003999-ADA2-47ED-A1E0-2572A00B6D75}']
  procedure DoSomething;
end;

IInterfaceY = interface(IInterface)
  ['{55BF8A92-FCE4-447D-B58B-26CD9B344EA7}']
  procedure DoNothing;
end;

TObjectB = class(TInterfacedObject, IInterfaceZ)
  procedure DoSomething;
end;

TObjectC = class(TInterfacedObject, IInterfaceY)
public
  FTest: string;
  procedure DoNothing;
end;

TObjectA = class(TInterfacedObject, IInterfaceZ, IInterfaceY)
private
  FInterfaceB: IInterfaceZ;
  FObjectC: TObjectC;
  function GetBB: IInterfaceZ;
public
  procedure AfterConstruction; override;
  procedure BeforeDestruction; override;
  property BB: IInterfaceZ read GetBB implements IInterfaceZ;
  property CC: TObjectC read FObjectC implements IInterfaceY;
end;

procedure TObjectB.DoSomething;
begin
  Sleep(1000);
end;

procedure TObjectA.AfterConstruction;
begin
  inherited;
  FInterfaceB := TObjectB.Create; …
Run Code Online (Sandbox Code Playgroud)

delphi interface reference-counting delphi-xe4

15
推荐指数
1
解决办法
3082
查看次数

有没有办法将shared_ptr <void>强制转换为shared_ptr <T>?

我想保持聪明的行为std::shared_ptr.那么有没有办法将共享的void指针转换为另一种类型而不会混淆引用计数?我无法获取原始指针并从中创建新的共享指针.

c++ reference-counting void-pointers shared-ptr

15
推荐指数
2
解决办法
5101
查看次数

为什么VC++字符串不被引用计数?

STL标准不要求从std :: string中重新计算.但事实上,大多数C++实现都提供了refcounted,copy-on-write字符串,允许您将值作为基本类型传递.此外,这些实现(至少g ++)使用原子操作使这些字符串无锁和线程安全.

简单的测试显示了写时复制语义:

#include <iostream>
#include <string>

using namespace std;

void foo(string s)
{
    cout<<(void*)s.c_str()<<endl;
    string ss=s;
    cout<<(void*)ss.c_str()<<endl;
    char p=ss[0];
    cout<<(void*)ss.c_str()<<endl;
}

int main()
{
    string s="coocko";
    cout<<(void*)s.c_str()<<endl;
    foo(s);
    cout<<(void*)s.c_str()<<endl;
}
Run Code Online (Sandbox Code Playgroud)

在使用非常数成员后,只有两个地址完全打印.

我使用HP,GCC和Intel编译器测试了这段代码,得到了类似的结果 - 字符串可以作为写时复制容器.

另一方面,VC++ 2005清楚地表明每个字符串都是完全复制的.

为什么?

我知道VC++ 6.0中存在一个错误,它具有非线程安全的引用计数实现,导致随机程序崩溃.这是什么原因?他们只是害怕再使用ref-count,即使这是常见的做法?他们宁愿不使用重新计算来解决问题吗?

谢谢

c++ string reference-counting copy-on-write visual-c++

13
推荐指数
4
解决办法
5202
查看次数

在不建模循环数据结构的单线程应用程序中何时需要引用计数?

Rust 可以非常优雅地处理引用计数Rc。社区的许多成员似乎不愿意使用它,而是使用该语言的所有权/借用语义。这使得编写的程序变得更简单,但是除了循环引用之外,还有必要吗?

显然,跨线程事情变得更加复杂,因此为了简化我想要学习的内容,“在单线程应用程序中,除了作为写入时优化之外,是否需要引用计数?” 这是 Rust 技能较高水平的反模式吗?

reference-counting rust

13
推荐指数
2
解决办法
1101
查看次数