我正在尝试用Java编写DagNode类,其中两个节点在逻辑上是相等的,如果它们等于作为引用.
C++中的想法 - (我来自C++) - 将使用智能指针和引用计数:
创建节点时,如果该节点已存在,我将在某个表中查找.如果是这样,我会返回指向旧指针的指针.否则,请创建一个新节点.
重载构造函数和析构函数等重载的C++方法将执行引用计数,当节点的引用计数降为0时,该节点将从上述表中逐出.(C++也将释放内存.)
但是,似乎没有办法在Java中自动进行ref-counting.我需要做裁判计数知道何时驱逐从表中的一个节点(以便它可以被垃圾收集),我真的想避免调用node->incRef(),并node->decRef()在每个函数的开始和结束.
我们如何在Java中使用这个C++习语?
下面的函数接受一个python文件句柄,从文件中读取打包的二进制数据,创建一个Python字典并返回它.如果我无休止地循环它,它将不断消耗RAM.我的RefCounting出了什么问题?
static PyObject* __binParse_getDBHeader(PyObject *self, PyObject *args){
PyObject *o; //generic object
PyObject* pyDB = NULL; //this has to be a py file object
if (!PyArg_ParseTuple(args, "O", &pyDB)){
return NULL;
} else {
Py_INCREF(pyDB);
if (!PyFile_Check(pyDB)){
Py_DECREF(pyDB);
PyErr_SetString(PyExc_IOError, "argument 1 must be open file handle");
return NULL;
}
}
FILE *fhDB = PyFile_AsFile(pyDB);
long offset = 0;
DB_HEADER *pdbHeader = malloc(sizeof(DB_HEADER));
fseek(fhDB,offset,SEEK_SET); //at the beginning
fread(pdbHeader, 1, sizeof(DB_HEADER), fhDB );
if (ferror(fhDB)){
fclose(fhDB);
Py_DECREF(pyDB);
PyErr_SetString(PyExc_IOError, "failed reading database header");
return NULL; …Run Code Online (Sandbox Code Playgroud) 关于如何实现线程安全引用计数器有很多问题.一个常见的高度评价的答案是:"使用原子增量/减量".好的,这是一个很好的方法来读取和写入refCounter whitout其他线程在其间更改它.但.
我的代码是:
void String::Release()
{
if ( 0 == AtomicDecrement( &refCounter ) ) )
delete buffer;
}
Run Code Online (Sandbox Code Playgroud)
所以.我安全地减少并阅读refCounter.但是,如果其他线程会在我将它与零比较时将INCREMENT我的refCounter怎么办?
我错了吗?
编辑:(示例)
String* globalString = new String(); // refCount == 1 after that.
// thread 0:
delete globalString;
// This invokes String::Release().
// After AtomicDecrement() counter becomes zero.
// Exactly after atomic decrement current thread switches to thread 1.
// thread 1:
String myCopy = *globalString;
// This invokes AddRef();
// globalString is alive;
// internal buffer is still not …Run Code Online (Sandbox Code Playgroud) 在进行std::shared_ptr大量工作时,我有点怀念shared_ref实现的过程。这是 的特化shared_ptr,它保证它永远不会包装 a nullptr(当然,给定正确的用法)。我有点想知道为什么它不在 C++11 标准中。执行过程中是否存在市长问题?我的头顶上什么也想不出来。
编辑:
我希望有一个类似于以下的界面:
template <typename T>
class shared_ref {
public:
shared_ref( T&& ref );
T& get();
T* operator&() const;
template< class Y >
void reset( Y&& obj );
long use_count() const;
bool unique() const;
void swap( shared_ref& r );
};
Run Code Online (Sandbox Code Playgroud) 我不明白以下行为.
locals()产生新的参考?locals()任何地方分配结果.X
import gc
from sys import getrefcount
def trivial(x): return x
def demo(x):
print getrefcount(x)
x = trivial(x)
print getrefcount(x)
locals()
print getrefcount(x)
gc.collect()
print getrefcount(x)
demo(object())
Run Code Online (Sandbox Code Playgroud)
输出是:
$ python demo.py
3
3
4
4
Run Code Online (Sandbox Code Playgroud) 我已经将泄漏问题减少到这个易于编译的代码中,该代码在CTFontCreateWithGraphicsFont使用和发布后显示ct_font,cg_font将留下一个额外的引用。这是 Apple 内部引用计数问题还是我错过了一些东西,例如必须双重发布cg_font或更改发布顺序?谢谢。
#include <stdio.h>
#include <stdlib.h>
#include <ApplicationServices/ApplicationServices.h>
int main(int argc, char **argv) {
FILE *f = fopen("/Library/Fonts/Tahoma.ttf", "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET);
char* font = (char*)malloc(fsize);
fread(font, fsize, 1, f);
fclose(f);
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, font, fsize, NULL);
CGFontRef cg_font = CGFontCreateWithDataProvider(provider);
CTFontRef ct_font = CTFontCreateWithGraphicsFont(cg_font, 36., NULL, NULL);
CGDataProviderRelease(provider);
//
CFRelease(ct_font);
CFRelease(cg_font);
printf("ct_font: %d\ncg_font: %d\n", (int)CFGetRetainCount(ct_font), (int)CFGetRetainCount(cg_font));
free(font);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译运行后的结果:
ct_font: …
我想知道为什么shared_ptr没有隐式构造函数.这里没有提到的事实:为此获取boost :: shared_ptr
(我想出了原因,但认为无论如何发布都是一个有趣的问题.)
#include <boost/shared_ptr.hpp>
#include <iostream>
using namespace boost;
using namespace std;
void fun(shared_ptr<int> ptr) {
cout << *ptr << endl;
}
int main() {
int foo = 5;
fun(&foo);
return 0;
}
/* shared_ptr_test.cpp: In function `int main()':
* shared_ptr_test.cpp:13: conversion from `int*' to non-scalar type `
* boost::shared_ptr<int>' requested */
Run Code Online (Sandbox Code Playgroud) $a=\$a;
Run Code Online (Sandbox Code Playgroud)
我正在阅读的这本书说在这种情况下$a永远不会是免费的,我的问题是为什么perl解释器在编译时没有修复它?当它发现它指向自身时,不要增加refcount.
为什么perl不这样做?
我正在维护一个使用 Python C API 作为 Python 扩展构建的 Python 类型。我的问题是关于这个“NamedArray”对象的生命周期。基本上我的测试代码如下所示:
def test_init_from_constructor(self):
"""
:return:
"""
n = NamedArray((2, 3))
self.assertIsInstance(n, NamedArray)
self.assertEqual(2, sys.getrefcount(n))
Run Code Online (Sandbox Code Playgroud)
我的问题是,新实例化的 NamedArray 对象的引用计数为 2,但我希望它为 1。另一个引用来自哪里?