我正在为持久存储的对象实现缓存.这个想法是:
getObjectFromPersistence(long id); ///Takes about 3 secondsgetObjectFromCache(long id) //Instantly并有一个方法:getObject(long id)使用以下伪代码:
synchronized(this){
CustomObject result= getObjectFromCache(id)
if (result==null){
result=getObjectFromPersistence(id);
addToCache(result);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
但我需要允许垃圾收集器收集CustomObject.到目前为止,我正在使用一个HashMap<Long,WeakReference<CustomObject>实现.问题是随着时间的推移HashMap变得空洞WeakReferences.
我已经检查了WeakHashMap但是键很弱(并且值仍然是强引用)所以使用WeakReferences的longs没有任何意义.
什么是解决这个问题的最佳解决方案?是否有一些"逆WeakHashMap"或类似的东西?
谢谢
不要SoftReference和WeakReference当为实例变量创建真的只有帮助吗?在方法范围内使用它们有什么好处吗?
另一个重要的部分是ReferenceQueue.除了能够跟踪确定垃圾的哪些引用外,还Reference.enqueue()可以用来强行注册垃圾回收对象?
例如,是否值得创建一个方法,该方法在对象中占用大量内存资源(由强引用持有)并创建引用以将它们排入队列?
Object bigObject;
public void dispose() {
ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
WeakReference<Object> ref = new WeakReference<Object>(bigObject, queue);
bigObject = null;
ref.enqueue();
}
Run Code Online (Sandbox Code Playgroud)
(想象一下,在这种情况下,Object表示一个使用大量内存的对象类型...喜欢BufferedImage什么的)
这有什么现实的效果吗?或者这只是浪费代码?
java memory garbage-collection weak-references soft-references
有没有办法在快速关闭中弱捕获多个参数?我知道这是弱写一个参数的语法:
{ [weak arg]
arg.doSomething()
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能为两个我想弱捕获的物体做这个?
我正试图坚持WeakKeyedDictionary<,>C#的真实细节......但我遇到了困难.
我意识到这是一个非常重要的任务,但似乎无法声明a WeakKeyedKeyValuePair<,>(如果密钥可达,GC只跟随值引用)使得它看起来似乎不可能.
我看到两个主要问题:
到目前为止,我所看到的每个实现都没有在收集密钥后修剪值.考虑一下 - 使用这样一个字典的主要原因之一是防止这些值被保留(不仅仅是键!),因为它们无法访问,但在这里它们被强引用指向.
是的,在词典中添加/删除足够多,它们最终会被替换,但是如果你不这样做呢?
如果没有一个假设WeakKeyedKeyValuePair<,>(或告诉GC到的另一种方法只标出值,如果关键是可达)是指它的键永远不会被收集的任何值.存储任意值时,这是一个问题.
问题1可以在一个相当不理想/ hackish的方式来解决:使用GC通知等待一个完整的GC完成,然后沿着去修剪字典在另一个线程.这个我半熟的.
但问题2让我难过.我意识到这很容易被"所以不要这样做"所抵消,但我想知道 - 这个问题甚至可以解决吗?
我想要做的是确保如果对我的观察者的唯一引用是可观察的,它会被垃圾收集并停止接收消息.
假设我有一个带有列表框的控件,名为Messages,后面是这个代码:
//Short lived display of messages (only while the user's viewing incoming messages)
public partial class MessageDisplay : UserControl
{
public MessageDisplay()
{
InitializeComponent();
MySource.IncomingMessages.Subscribe(m => Messages.Items.Add(m));
}
}
Run Code Online (Sandbox Code Playgroud)
哪个连接到此来源:
//Long lived location for message store
static class MySource
{
public readonly static IObservable<string> IncomingMessages = new ReplaySubject<string>;
}
Run Code Online (Sandbox Code Playgroud)
我不想要的是让消息显示器在不再可见后很长时间内保存在内存中.理想情况下,我想要一点延伸,所以我可以写:
MySource.IncomingMessages.ToWeakObservable().Subscribe(m => Messages.Items.Add(m));
Run Code Online (Sandbox Code Playgroud)
我也不想依赖MessageDisplay是一个用户控件的事实,因为我稍后想要使用MessageDisplayViewModel进行MVVM设置,这不是用户控件.
我知道OBJC_ASSOCIATION_ASSIGN存在,但是如果目标对象被释放,它是否会将引用归零?或者它是否像旧时代那样需要获取nil-ed或者我们以后会冒错误访问?
在多线程Android项目中,我看到的代码如下:
final WeakReference<MyClass> myClassObjectWeakRef =
new WeakReference<MyClass>(aMyClassObject);
Run Code Online (Sandbox Code Playgroud)
......然后在其他地方:
if (myClassObjectWeakRef.get() != null) {
myClassObjectWeakRef.get().someMethod();
}
Run Code Online (Sandbox Code Playgroud)
我很确定在检查和引用的使用之间可能存在竞争条件,如果对象的最后一个强引用是在另一个线程中的两个之间释放,但我找不到任何文档或任何人/ /谁可以比"你可能是对的"更好地证实这一点.
我认为测试和使用弱引用的唯一正确方法是这样做的:
MyClass myObject = myClassObjectWeakRef.get();
// we now have a strong reference, or null: standard checks apply.
if (myObject != null) {
myObject.someMethod();
}
Run Code Online (Sandbox Code Playgroud)
我非常有信心,第二个方法是100%安全的,但我不知道是否有一些Java /编译糖/魔法,我不知道,这会使得第一种方法是安全的.
那么,第一种方法是否100%安全?
在Clang的Objective-C自动参考计数中,我们看到以下内容
对于__weak对象,左值更新为指向新的指针,除非新指针是当前正在进行解除分配的对象,在这种情况下,左值更新为空指针.这必须相对于对象的其他赋值,从对象读取以及新指针的最终版本以原子方式执行.
在objc-weak.mm中,我们看到以下代码块weak_register_no_lock():
if (deallocating) {
if (crashIfDeallocating) {
_objc_fatal("Cannot form weak reference to instance (%p) of "
"class %s. It is possible that this object was "
"over-released, or is in the process of deallocation.",
(void*)referent, object_getClassName((id)referent));
} else {
return nil;
}
}
Run Code Online (Sandbox Code Playgroud)
我在我的UIViewController子类dealloc方法中设置了一个断点,并尝试[self allowsWeakReference]在lldb中调用,从而产生了NO值.
如果我们尝试将self设置为另一个对象的weak属性,则应用程序将根据objc-weak.mm代码崩溃.
问题是 - 为什么会发生这种情况?铿锵的规格是错的吗?这是objc实现中的一个错误吗?
这是一段简单的代码,可以重现崩溃:
//cc -fmodules -fobjc-arc -g crash.m -o crash
@import Foundation;
@interface Foo : NSObject
@end
@implementation Foo …Run Code Online (Sandbox Code Playgroud) weak-references objective-c clang dealloc automatic-ref-counting
我正在开发一个iPhone应用程序.我有一个类的对象Row需要释放该类的许多对象Block.每个Block当前都有一个保留类的实例变量的属性Row.
@interface Block : UIImageView {
Row *yCoord;
}
@property (nonatomic,retain) Row *yCoord;
@end
Run Code Online (Sandbox Code Playgroud)
每个Row包含NSMutableArray这些块中的一个.
@interface Row : NSObject {
NSMutableArray *blocks;
}
-(void)addBlock:(Block*)aBlock;
@end
@implementation Row
-(void)addBlock:(Block*)aBlock {
[blocks addObject:aBlock];
aBlock.yCoord = self;
}
@end
Run Code Online (Sandbox Code Playgroud)
我知道这是一个循环参考.Apple的文档声明,为了使用循环引用释放对象,我需要一个弱引用而不是一个强引用(一个保留属性),但它没有贯彻并解释我究竟是如何做到的.我计划同时释放和释放一行中的所有块以及行本身.如何在每个块中将弱引用设置为"父"行?
使用一个List<WeakReference>将无法正常工作.我想要的是,只要他们引用的对象被垃圾收集,就会自动从列表中删除 WeakReferences .
ConditionalWeakTable<TKey,TValue> 也不满足我,因为虽然它的键和值被弱引用和收集,但你不能枚举它们!
weak-references ×10
java ×3
objective-c ×3
.net ×2
android ×2
c# ×2
clang ×1
closures ×1
dealloc ×1
dictionary ×1
hashmap ×1
iphone ×1
memory ×1
swift ×1