只是为了它的纯粹,我决定创建一个绑定到libpython的Scheme,这样你就可以在Scheme程序中嵌入Python.我已经能够调用Python的C API,但我还没有真正考虑过内存管理.
mzscheme的FFI工作方式是我可以调用一个函数,如果该函数返回指向a的指针PyObject,那么我可以自动增加引用计数.然后,我可以注册一个终结器,当Scheme对象被垃圾收集时,它会减少引用计数.我已经查看了文档以供参考计数,并且乍一看没有看到任何问题(尽管在某些情况下它可能不是最佳的).我有什么陷阱吗?
此外,我无法制作循环垃圾收集器文档的正面或反面.我需要记住哪些事情?特别是,我如何让Python知道我有一些东西的引用,所以当我还在使用它时它不会收集它?
python scheme garbage-collection reference-counting python-c-api
直到五分钟我才确定我对Objective c引用计数的理解非常好,但是当我开始检查对象retainCount时,我很惊讶地看到我所看到的.
例如,myViewController有一个UITableview:
.h文件
@interface RegularChatViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
{
UITableView *_tableView;
}
@property (nonatomic, retain) IBOutlet UITableView *tableView;
Run Code Online (Sandbox Code Playgroud)
.m文件
@synthesize tableView = _tableView;
- (void)loadView
{
_tableView = [[UITableView alloc] init]; // STEP ONE
NSLog(@"tableView retain count: %d",[_tableView retainCount]);
self.tableView.frame = CGRectMake(0, 0, 320, tableHeight); // STEP TWO
NSLog(@"tableView retain count: %d",[_tableView retainCount]);
[self.view addSubview:self.tableView]; // STEP THREE
NSLog(@"tableView retain count: %d",[_tableView retainCount]);
}
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,输入是:
tableView retain count: 1
tableView retain count: 2
tableView retain count: 3
Run Code Online (Sandbox Code Playgroud)
显然,STEP …
我正在参加关于编译器的大学课程,我们刚刚讨论了垃圾收集和释放内存的方法.然而,在课堂讲座和我们的教科书中,我被引导相信引用计数不是管理记忆的好方法.
原因是引用计数非常昂贵,因为程序必须插入许多附加指令来递增和递减引用计数.此外,每次引用计数更改时,程序必须检查它是否等于零,如果是,则回收内存.
我的教科书甚至还有一句话:"总的来说,引用计数的问题超出了它的优点,很少用于编程语言环境中的自动存储管理.
我的问题是:这些合法性问题是否存在?Objective-c是否以某种方式避免它们?如果是这样的话?
garbage-collection reference-counting objective-c ios automatic-ref-counting
我正在使用ctypes从python中使用C库.有一个带有void*参数的回调函数我用作ctypes.py_object.注册回调时,对象指针将提供给库.但是当它不再从python代码引用时,它应该被销毁.我希望它能够存活,直到调用回调函数.我怎么做?
callback_t=ctypes.CFUNCTYPE(None, ctypes.py_object)
clib.register_callback.argtypes=[callback_t, ctypes.py_object]
clib.register_callback.restype=None
class Object:
def __init__(self, val):
self.val=val
def callback(obj):
print(obj.val)
callback_c=callback_t(callback)
def calledByOtherCode(val):
clib.register_callback(callback_c, Object(val))
Run Code Online (Sandbox Code Playgroud) 作为Rust的学习项目,我有一个非常简单(工作,如果不完整)的单链表实现.结构的声明如下:
type NodePtr<T> = Option<Box<Node<T>>>;
struct Node<T> {
data: T,
next: NodePtr<T>,
}
pub struct LinkedList<T> {
head: NodePtr<T>,
}
Run Code Online (Sandbox Code Playgroud)
实施size并且push_front都是相当直接的,尽管迭代地执行大小确实涉及一些"与借用检查员打架".
我想要尝试的下一件事是添加一个tail指向LinkedList结构的指针.实现高效push_back运营.在这里,我遇到了一堵墙.起初我试图使用Option<&Box<Node<T>>>然后Option<&Node<T>>.这两个都导致了'a无处不在,但最终仍然无法承诺tail有效的终身检查.
我已经得出了一个初步结论:这些定义是不可能的:没有办法保证编译器tail在我认为有效的地方有效.我可以实现这一目标的唯一方法是让我的所有指针都是Rc<_>或者Rc<RefCell<_>>,因为那些是指向同一个对象(最终节点)的两个东西的唯一安全方法.
我的问题:这是正确的结论吗?更一般地说:对于数据结构中的无主指针,什么是惯用的Rust解决方案?在我看来,引用计数对于如此简单的事情看起来非常重,所以我认为我必须遗漏一些东西.(或者我可能还没有考虑到对于记忆安全的正确心态.)
似乎MapViewOfFile增加了文件映射内核对象的引用计数.
引自MSDN描述MapViewOfFile:
文件映射对象的映射视图维护对象的内部引用,并且文件映射对象在释放对它的所有引用之前不会关闭.因此,要完全关闭文件映射对象,应用程序必须通过调用
UnmapViewOfFile并通过调用并关闭文件映射对象句柄来取消映射文件映射对象的所有映射视图CloseHandle.可以按任何顺序调用这些函数.
此外,从Windows到C/C++,第5版:
上面的代码显示了用于操作内存映射文件的"预期"方法.但是,它没有显示的是,当您调用时,系统会增加文件对象和文件映射对象的使用计数
MapViewOfFile...
尽管如此,我的实际测试表明相反.我在Windows 10 64位上使用Visual Studio 2015.测试程序如下:
#include <windows.h>
int main() {
HANDLE h = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 128, "test");
void* p_memory = MapViewOfFile(h, FILE_MAP_WRITE, 0, 0, 0);
CloseHandle(h);
h = OpenFileMappingA(FILE_MAP_WRITE, FALSE, "test");
DWORD dw = GetLastError(); // ERROR_FILE_NOT_FOUND
}
Run Code Online (Sandbox Code Playgroud)
OpenFileMapping呼叫因上一个错误而失败ERROR_FILE_NOT_FOUND.当我取消CloseHandle通话时,一切都会好的.这意味着该CloseHandle调用消除了文件映射内核对象的最后引用计数并将其销毁.这反过来意味着MapViewOfFile实际上不会增加对象的引用计数.
我想确定发生了什么,以及MapViewOfFile关于文件映射内核对象的引用计数的确切语义是什么.
我有两个类(在我的示例中为TObject1和TObject2),它们通过接口(IObject1,IObject2)相互了解.正如您在Delphi中可能知道的那样,这将导致内存泄漏,因为参考计数器将始终保持在零以上.通常的解决方案是将一个引用声明为弱.这在大多数情况下都适用,因为你通常知道哪一个会被破坏,或者一旦它被销毁就不一定需要弱引用后面的对象.
这说我尝试以这样的方式解决问题,即两个对象都保持活着,直到两者都不再被引用:(因为我使用[unsafe]属性需要Delphi 10.1)
program Project14;
{$APPTYPE CONSOLE}
uses
System.SysUtils;
type
IObject2 = interface;
IObject1 = interface
['{F68D7631-4838-4E15-871A-BD2EAF16CC49}']
function GetObject2: IObject2;
end;
IObject2 = interface
['{98EB60DA-646D-4ECF-B5A7-6A27B3106689}']
end;
TObject1 = class(TInterfacedObject, IObject1)
[unsafe] FObj2: IObject2;
constructor Create;
destructor Destroy; override;
function GetObject2: IObject2;
end;
TObject2 = class(TContainedObject, IObject2)
[unsafe] FObj1: IObject1;
constructor Create(aObj1: IObject1);
destructor Destroy; override;
end;
constructor TObject1.Create;
begin
FObj2 := TObject2.Create(Self);
end;
destructor TObject1.Destroy;
begin
TContainedObject(FObj2).Free;
inherited Destroy;
end;
function TObject1.GetObject2: IObject2;
begin
Result := FObj2;
end;
constructor TObject2.Create(aObj1: …Run Code Online (Sandbox Code Playgroud) 此性能优化WWDC视频表明字符串是引用计数的,因为它们在堆上.这对使用Strings的结构的性能以及Swift 4中是否有某些变化有影响(现在Strings又是集合 - 带有写入时的副本).好奇如何证明这一点并获得实际计数. CFGetRetainCount - 不适用于字符串.
请参阅https://developer.apple.com/videos/play/wwdc2016/416/
使用Swift 4.
鉴于此类是enable_shared_from_this:
class connection : public std::enable_shared_from_this<connection>
{
//...
};
Run Code Online (Sandbox Code Playgroud)
假设我创建的两个实例std::shared_ptr来自同一 connection*如下:
std::shared_ptr<connection> rc(new connection);
std::shared_ptr<connection> fc(rc.get(), [](connection const * c) {
std::cout << "fake delete" << std::endl;
});
Run Code Online (Sandbox Code Playgroud)
到目前为止它的好处,因为资源{ connection*}由一个单独 拥有shared_ptr- rc确切地说,并且fc只有一个假的删除器.
在那之后,我这样做:
auto sc = fc->shared_from_this();
//OR auto sc = rc->shared_from_this(); //does not make any difference!
Run Code Online (Sandbox Code Playgroud)
现在哪个shared_ptr- rc或fc- 将sc 与其分享其引用计数?换一种说法,
std::cout << rc->use_count() << std::endl;
std::cout << fc->use_count() …Run Code Online (Sandbox Code Playgroud) c++ reference-counting shared-ptr weak-ptr enable-shared-from-this
我有一个问题,请通过以下简单的C++程序,
int main( )
{
shared_ptr<int> sptr1( new int );
shared_ptr<int> sptr2 = sptr1;
shared_ptr<int> sptr3;
shared_ptr<int> sptr4;
sptr3 = sptr2;
cout<<sptr1.use_count()<<endl;
cout<<sptr2.use_count()<<endl;
cout<<sptr3.use_count()<<endl;
sptr4 = sptr2;
cout<<sptr1.use_count()<<endl;
cout<<sptr2.use_count()<<endl;
cout<<sptr3.use_count()<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
3
3
3
4
4
4
Run Code Online (Sandbox Code Playgroud)
如何sptr1和sptr3对象知道引用计数在打印4时递增.
据我所知,引用计数是每个shared_ptr对象中的变量.
c++ ×3
ios ×2
objective-c ×2
python ×2
shared-ptr ×2
ctypes ×1
delphi ×1
interface ×1
iphone ×1
linked-list ×1
optimization ×1
performance ×1
python-c-api ×1
retaincount ×1
rust ×1
scheme ×1
string ×1
swift ×1
weak-ptr ×1
winapi ×1
windows ×1