The correct way to store some metadata associated with an object?
Firstly I'm afraid of the memory leak issue here. Because what I do is using some Dictionary to store the metadata with Key of the object itself. So I can lookup for metadata (which should be dynamic) by passing in the object.
Note that the object here does not have any GUID to help identify itself, the only way to identify it is by its instance.
This kind of storing looks much like what in DependencyObject
in WPF. We can declare DependencyProperty
(attached property) to extend the DependencyObject
(the metadata is contained in the attached property).
Here is what I have:
Dictionary<object, SomeMetaData> _metadataLookup = new Dictionary<object,SomeMetaData>();
//to store metadata
_metadataLookup[someObject] = someMetaData;
//to get metadata
SomeMetaData someMetaData;
_metadataLookup.TryGetValue(someObject, out someMetaData);
It would be fine if the someObject
's lifetime is the same as the lifetime of the scope using the _metadataLookup
. But what if the someObject
(after stored in _metadataLookup
) should be destroyed (logically become unused)? We have to manually remove it from _metadataLookup
as well, otherwise there is a memory leak there.
I'm seeking for a better solution for this issue, unexpectedly forgetting to remove the objects manually or simply not knowing when the objects should be removed is a problem here. Thanks.
c# caching memory-leaks metadata
add a comment |
Firstly I'm afraid of the memory leak issue here. Because what I do is using some Dictionary to store the metadata with Key of the object itself. So I can lookup for metadata (which should be dynamic) by passing in the object.
Note that the object here does not have any GUID to help identify itself, the only way to identify it is by its instance.
This kind of storing looks much like what in DependencyObject
in WPF. We can declare DependencyProperty
(attached property) to extend the DependencyObject
(the metadata is contained in the attached property).
Here is what I have:
Dictionary<object, SomeMetaData> _metadataLookup = new Dictionary<object,SomeMetaData>();
//to store metadata
_metadataLookup[someObject] = someMetaData;
//to get metadata
SomeMetaData someMetaData;
_metadataLookup.TryGetValue(someObject, out someMetaData);
It would be fine if the someObject
's lifetime is the same as the lifetime of the scope using the _metadataLookup
. But what if the someObject
(after stored in _metadataLookup
) should be destroyed (logically become unused)? We have to manually remove it from _metadataLookup
as well, otherwise there is a memory leak there.
I'm seeking for a better solution for this issue, unexpectedly forgetting to remove the objects manually or simply not knowing when the objects should be removed is a problem here. Thanks.
c# caching memory-leaks metadata
Yeah storing the reference is probably not a good thing. however you could store the hashcode, though you will have to implement it properly
– Michael Randall
Nov 21 '18 at 2:39
@TheGeneral thanks, are you sure that the Hash code could help identify the objects without any contention?
– Hopeless
Nov 21 '18 at 2:40
add a comment |
Firstly I'm afraid of the memory leak issue here. Because what I do is using some Dictionary to store the metadata with Key of the object itself. So I can lookup for metadata (which should be dynamic) by passing in the object.
Note that the object here does not have any GUID to help identify itself, the only way to identify it is by its instance.
This kind of storing looks much like what in DependencyObject
in WPF. We can declare DependencyProperty
(attached property) to extend the DependencyObject
(the metadata is contained in the attached property).
Here is what I have:
Dictionary<object, SomeMetaData> _metadataLookup = new Dictionary<object,SomeMetaData>();
//to store metadata
_metadataLookup[someObject] = someMetaData;
//to get metadata
SomeMetaData someMetaData;
_metadataLookup.TryGetValue(someObject, out someMetaData);
It would be fine if the someObject
's lifetime is the same as the lifetime of the scope using the _metadataLookup
. But what if the someObject
(after stored in _metadataLookup
) should be destroyed (logically become unused)? We have to manually remove it from _metadataLookup
as well, otherwise there is a memory leak there.
I'm seeking for a better solution for this issue, unexpectedly forgetting to remove the objects manually or simply not knowing when the objects should be removed is a problem here. Thanks.
c# caching memory-leaks metadata
Firstly I'm afraid of the memory leak issue here. Because what I do is using some Dictionary to store the metadata with Key of the object itself. So I can lookup for metadata (which should be dynamic) by passing in the object.
Note that the object here does not have any GUID to help identify itself, the only way to identify it is by its instance.
This kind of storing looks much like what in DependencyObject
in WPF. We can declare DependencyProperty
(attached property) to extend the DependencyObject
(the metadata is contained in the attached property).
Here is what I have:
Dictionary<object, SomeMetaData> _metadataLookup = new Dictionary<object,SomeMetaData>();
//to store metadata
_metadataLookup[someObject] = someMetaData;
//to get metadata
SomeMetaData someMetaData;
_metadataLookup.TryGetValue(someObject, out someMetaData);
It would be fine if the someObject
's lifetime is the same as the lifetime of the scope using the _metadataLookup
. But what if the someObject
(after stored in _metadataLookup
) should be destroyed (logically become unused)? We have to manually remove it from _metadataLookup
as well, otherwise there is a memory leak there.
I'm seeking for a better solution for this issue, unexpectedly forgetting to remove the objects manually or simply not knowing when the objects should be removed is a problem here. Thanks.
c# caching memory-leaks metadata
c# caching memory-leaks metadata
asked Nov 21 '18 at 2:35
HopelessHopeless
1,91821729
1,91821729
Yeah storing the reference is probably not a good thing. however you could store the hashcode, though you will have to implement it properly
– Michael Randall
Nov 21 '18 at 2:39
@TheGeneral thanks, are you sure that the Hash code could help identify the objects without any contention?
– Hopeless
Nov 21 '18 at 2:40
add a comment |
Yeah storing the reference is probably not a good thing. however you could store the hashcode, though you will have to implement it properly
– Michael Randall
Nov 21 '18 at 2:39
@TheGeneral thanks, are you sure that the Hash code could help identify the objects without any contention?
– Hopeless
Nov 21 '18 at 2:40
Yeah storing the reference is probably not a good thing. however you could store the hashcode, though you will have to implement it properly
– Michael Randall
Nov 21 '18 at 2:39
Yeah storing the reference is probably not a good thing. however you could store the hashcode, though you will have to implement it properly
– Michael Randall
Nov 21 '18 at 2:39
@TheGeneral thanks, are you sure that the Hash code could help identify the objects without any contention?
– Hopeless
Nov 21 '18 at 2:40
@TheGeneral thanks, are you sure that the Hash code could help identify the objects without any contention?
– Hopeless
Nov 21 '18 at 2:40
add a comment |
1 Answer
1
active
oldest
votes
For this purpose you can use ConditionalWeakTable
public class Example
{
public static void Main()
{
var mc1 = new ManagedClass();
var mc2 = new ManagedClass();
var mc3 = new ManagedClass();
var cwt = new ConditionalWeakTable<ManagedClass, ClassData>();
cwt.Add(mc1, new ClassData());
cwt.Add(mc2, new ClassData());
cwt.Add(mc3, new ClassData());
var wr2 = new WeakReference(mc2);
mc2 = null;
GC.Collect();
ClassData data = null;
if (wr2.Target == null)
Console.WriteLine("No strong reference to mc2 exists.");
else if (cwt.TryGetValue(mc2, out data))
Console.WriteLine("Data created at {0}", data.CreationTime);
else
Console.WriteLine("mc2 not found in the table.");
}
}
public class ManagedClass
{
}
public class ClassData
{
public DateTime CreationTime;
public object Data;
public ClassData()
{
CreationTime = DateTime.Now;
this.Data = new object();
}
}
// The example displays the following output:
// No strong reference to mc2 exists.
I learn something new each day, upvote
– Michael Randall
Nov 21 '18 at 2:40
thank you for this, it looks like that theConditionalWeakTable
is a tool of compiler services. Is it fine to just use it in our own code? I'm afraid of its change in future. One more thing I would like to have here is some concurrent version of thisConditionalWeakTable
? Yes actually in my scenario I may have to lookup for the data concurrently. Anyway this answer is great but I still leave this question open for a while. Thanks again.
– Hopeless
Nov 21 '18 at 2:55
1
@Hopeless, as docs said: Instances of the ConditionalWeakTable<TKey,TValue> class are thread safe. They do not require callers to do any additional locking.
– vasily.sib
Nov 21 '18 at 3:25
@Hopeless it's hard to tell, is it ok or not. ButConditionalWeakTable
seems ok for situation you have described
– Backs
Nov 21 '18 at 6:46
thanks, at least I have no other way, maybe some look into the source code of WPF for implementation ofDependencyObject
andDependencyProperty
will provide another solution.
– Hopeless
Nov 23 '18 at 3:04
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404550%2fthe-correct-way-to-store-some-metadata-associated-with-an-object%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
For this purpose you can use ConditionalWeakTable
public class Example
{
public static void Main()
{
var mc1 = new ManagedClass();
var mc2 = new ManagedClass();
var mc3 = new ManagedClass();
var cwt = new ConditionalWeakTable<ManagedClass, ClassData>();
cwt.Add(mc1, new ClassData());
cwt.Add(mc2, new ClassData());
cwt.Add(mc3, new ClassData());
var wr2 = new WeakReference(mc2);
mc2 = null;
GC.Collect();
ClassData data = null;
if (wr2.Target == null)
Console.WriteLine("No strong reference to mc2 exists.");
else if (cwt.TryGetValue(mc2, out data))
Console.WriteLine("Data created at {0}", data.CreationTime);
else
Console.WriteLine("mc2 not found in the table.");
}
}
public class ManagedClass
{
}
public class ClassData
{
public DateTime CreationTime;
public object Data;
public ClassData()
{
CreationTime = DateTime.Now;
this.Data = new object();
}
}
// The example displays the following output:
// No strong reference to mc2 exists.
I learn something new each day, upvote
– Michael Randall
Nov 21 '18 at 2:40
thank you for this, it looks like that theConditionalWeakTable
is a tool of compiler services. Is it fine to just use it in our own code? I'm afraid of its change in future. One more thing I would like to have here is some concurrent version of thisConditionalWeakTable
? Yes actually in my scenario I may have to lookup for the data concurrently. Anyway this answer is great but I still leave this question open for a while. Thanks again.
– Hopeless
Nov 21 '18 at 2:55
1
@Hopeless, as docs said: Instances of the ConditionalWeakTable<TKey,TValue> class are thread safe. They do not require callers to do any additional locking.
– vasily.sib
Nov 21 '18 at 3:25
@Hopeless it's hard to tell, is it ok or not. ButConditionalWeakTable
seems ok for situation you have described
– Backs
Nov 21 '18 at 6:46
thanks, at least I have no other way, maybe some look into the source code of WPF for implementation ofDependencyObject
andDependencyProperty
will provide another solution.
– Hopeless
Nov 23 '18 at 3:04
add a comment |
For this purpose you can use ConditionalWeakTable
public class Example
{
public static void Main()
{
var mc1 = new ManagedClass();
var mc2 = new ManagedClass();
var mc3 = new ManagedClass();
var cwt = new ConditionalWeakTable<ManagedClass, ClassData>();
cwt.Add(mc1, new ClassData());
cwt.Add(mc2, new ClassData());
cwt.Add(mc3, new ClassData());
var wr2 = new WeakReference(mc2);
mc2 = null;
GC.Collect();
ClassData data = null;
if (wr2.Target == null)
Console.WriteLine("No strong reference to mc2 exists.");
else if (cwt.TryGetValue(mc2, out data))
Console.WriteLine("Data created at {0}", data.CreationTime);
else
Console.WriteLine("mc2 not found in the table.");
}
}
public class ManagedClass
{
}
public class ClassData
{
public DateTime CreationTime;
public object Data;
public ClassData()
{
CreationTime = DateTime.Now;
this.Data = new object();
}
}
// The example displays the following output:
// No strong reference to mc2 exists.
I learn something new each day, upvote
– Michael Randall
Nov 21 '18 at 2:40
thank you for this, it looks like that theConditionalWeakTable
is a tool of compiler services. Is it fine to just use it in our own code? I'm afraid of its change in future. One more thing I would like to have here is some concurrent version of thisConditionalWeakTable
? Yes actually in my scenario I may have to lookup for the data concurrently. Anyway this answer is great but I still leave this question open for a while. Thanks again.
– Hopeless
Nov 21 '18 at 2:55
1
@Hopeless, as docs said: Instances of the ConditionalWeakTable<TKey,TValue> class are thread safe. They do not require callers to do any additional locking.
– vasily.sib
Nov 21 '18 at 3:25
@Hopeless it's hard to tell, is it ok or not. ButConditionalWeakTable
seems ok for situation you have described
– Backs
Nov 21 '18 at 6:46
thanks, at least I have no other way, maybe some look into the source code of WPF for implementation ofDependencyObject
andDependencyProperty
will provide another solution.
– Hopeless
Nov 23 '18 at 3:04
add a comment |
For this purpose you can use ConditionalWeakTable
public class Example
{
public static void Main()
{
var mc1 = new ManagedClass();
var mc2 = new ManagedClass();
var mc3 = new ManagedClass();
var cwt = new ConditionalWeakTable<ManagedClass, ClassData>();
cwt.Add(mc1, new ClassData());
cwt.Add(mc2, new ClassData());
cwt.Add(mc3, new ClassData());
var wr2 = new WeakReference(mc2);
mc2 = null;
GC.Collect();
ClassData data = null;
if (wr2.Target == null)
Console.WriteLine("No strong reference to mc2 exists.");
else if (cwt.TryGetValue(mc2, out data))
Console.WriteLine("Data created at {0}", data.CreationTime);
else
Console.WriteLine("mc2 not found in the table.");
}
}
public class ManagedClass
{
}
public class ClassData
{
public DateTime CreationTime;
public object Data;
public ClassData()
{
CreationTime = DateTime.Now;
this.Data = new object();
}
}
// The example displays the following output:
// No strong reference to mc2 exists.
For this purpose you can use ConditionalWeakTable
public class Example
{
public static void Main()
{
var mc1 = new ManagedClass();
var mc2 = new ManagedClass();
var mc3 = new ManagedClass();
var cwt = new ConditionalWeakTable<ManagedClass, ClassData>();
cwt.Add(mc1, new ClassData());
cwt.Add(mc2, new ClassData());
cwt.Add(mc3, new ClassData());
var wr2 = new WeakReference(mc2);
mc2 = null;
GC.Collect();
ClassData data = null;
if (wr2.Target == null)
Console.WriteLine("No strong reference to mc2 exists.");
else if (cwt.TryGetValue(mc2, out data))
Console.WriteLine("Data created at {0}", data.CreationTime);
else
Console.WriteLine("mc2 not found in the table.");
}
}
public class ManagedClass
{
}
public class ClassData
{
public DateTime CreationTime;
public object Data;
public ClassData()
{
CreationTime = DateTime.Now;
this.Data = new object();
}
}
// The example displays the following output:
// No strong reference to mc2 exists.
answered Nov 21 '18 at 2:39
BacksBacks
19.2k33159
19.2k33159
I learn something new each day, upvote
– Michael Randall
Nov 21 '18 at 2:40
thank you for this, it looks like that theConditionalWeakTable
is a tool of compiler services. Is it fine to just use it in our own code? I'm afraid of its change in future. One more thing I would like to have here is some concurrent version of thisConditionalWeakTable
? Yes actually in my scenario I may have to lookup for the data concurrently. Anyway this answer is great but I still leave this question open for a while. Thanks again.
– Hopeless
Nov 21 '18 at 2:55
1
@Hopeless, as docs said: Instances of the ConditionalWeakTable<TKey,TValue> class are thread safe. They do not require callers to do any additional locking.
– vasily.sib
Nov 21 '18 at 3:25
@Hopeless it's hard to tell, is it ok or not. ButConditionalWeakTable
seems ok for situation you have described
– Backs
Nov 21 '18 at 6:46
thanks, at least I have no other way, maybe some look into the source code of WPF for implementation ofDependencyObject
andDependencyProperty
will provide another solution.
– Hopeless
Nov 23 '18 at 3:04
add a comment |
I learn something new each day, upvote
– Michael Randall
Nov 21 '18 at 2:40
thank you for this, it looks like that theConditionalWeakTable
is a tool of compiler services. Is it fine to just use it in our own code? I'm afraid of its change in future. One more thing I would like to have here is some concurrent version of thisConditionalWeakTable
? Yes actually in my scenario I may have to lookup for the data concurrently. Anyway this answer is great but I still leave this question open for a while. Thanks again.
– Hopeless
Nov 21 '18 at 2:55
1
@Hopeless, as docs said: Instances of the ConditionalWeakTable<TKey,TValue> class are thread safe. They do not require callers to do any additional locking.
– vasily.sib
Nov 21 '18 at 3:25
@Hopeless it's hard to tell, is it ok or not. ButConditionalWeakTable
seems ok for situation you have described
– Backs
Nov 21 '18 at 6:46
thanks, at least I have no other way, maybe some look into the source code of WPF for implementation ofDependencyObject
andDependencyProperty
will provide another solution.
– Hopeless
Nov 23 '18 at 3:04
I learn something new each day, upvote
– Michael Randall
Nov 21 '18 at 2:40
I learn something new each day, upvote
– Michael Randall
Nov 21 '18 at 2:40
thank you for this, it looks like that the
ConditionalWeakTable
is a tool of compiler services. Is it fine to just use it in our own code? I'm afraid of its change in future. One more thing I would like to have here is some concurrent version of this ConditionalWeakTable
? Yes actually in my scenario I may have to lookup for the data concurrently. Anyway this answer is great but I still leave this question open for a while. Thanks again.– Hopeless
Nov 21 '18 at 2:55
thank you for this, it looks like that the
ConditionalWeakTable
is a tool of compiler services. Is it fine to just use it in our own code? I'm afraid of its change in future. One more thing I would like to have here is some concurrent version of this ConditionalWeakTable
? Yes actually in my scenario I may have to lookup for the data concurrently. Anyway this answer is great but I still leave this question open for a while. Thanks again.– Hopeless
Nov 21 '18 at 2:55
1
1
@Hopeless, as docs said: Instances of the ConditionalWeakTable<TKey,TValue> class are thread safe. They do not require callers to do any additional locking.
– vasily.sib
Nov 21 '18 at 3:25
@Hopeless, as docs said: Instances of the ConditionalWeakTable<TKey,TValue> class are thread safe. They do not require callers to do any additional locking.
– vasily.sib
Nov 21 '18 at 3:25
@Hopeless it's hard to tell, is it ok or not. But
ConditionalWeakTable
seems ok for situation you have described– Backs
Nov 21 '18 at 6:46
@Hopeless it's hard to tell, is it ok or not. But
ConditionalWeakTable
seems ok for situation you have described– Backs
Nov 21 '18 at 6:46
thanks, at least I have no other way, maybe some look into the source code of WPF for implementation of
DependencyObject
and DependencyProperty
will provide another solution.– Hopeless
Nov 23 '18 at 3:04
thanks, at least I have no other way, maybe some look into the source code of WPF for implementation of
DependencyObject
and DependencyProperty
will provide another solution.– Hopeless
Nov 23 '18 at 3:04
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404550%2fthe-correct-way-to-store-some-metadata-associated-with-an-object%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Yeah storing the reference is probably not a good thing. however you could store the hashcode, though you will have to implement it properly
– Michael Randall
Nov 21 '18 at 2:39
@TheGeneral thanks, are you sure that the Hash code could help identify the objects without any contention?
– Hopeless
Nov 21 '18 at 2:40