I have written a managed class that wraps around an unmanaged C++ object, but I found that - when using it in C# - the GC kicks in early while I'm executing a method on the object. I have read up on garbage collection and how to prevent it from happening early. One way is to use a "using" statement to control when the object is disposed, but this puts the responsibility on the client of the managed object. I could add to the managed class:
MyManagedObject::MyMethod()
{
System::Runtime::InteropServices::GCHandle handle =
System::Runtime::InteropServices::GCHandle::Alloc(this);
// access unmanaged member
handle.Free();
}
This appears to work. Being new to .NET, how do other people deal with this problem?
Thank you,
Johan
You might like to take a look at this article: http://www.codeproject.com/Tips/246372/Premature-NET-garbage-collection-or-Dude-wheres-my. I believe it describes your situation exactly. In short, the remedies are either ausing block or a GC.KeepAlive. However, I agree that in many cases you will not wish to pass this burden onto the client of the unmanaged object; in this case, a call to GC.KeepAlive(this) at the end of every wrapper method is a good solution.
You can use GC.KeepAlive(this) in your method's body if you want to keep the finalizer from being called. As others noted correctly in the comments, if your this reference is not live during the method call, it is possible for the finalizer to be called and for memory to be reclaimed during the call.
See http://blogs.microsoft.co.il/blogs/sasha/archive/2008/07/28/finalizer-vs-application-a-race-condition-from-hell.aspx for a detailed case study.
Related
Can I have an boost::promise<void> created in a thread and set its value in another different thread through boost::promise<void>::set_value().
I think I am having a crash because of this, probably, so I must guess that no, but I would need confirmation. Thanks in advance.
P.S.: Note that I am using boost implementation.
Yes, you can do that, but you must ensure that the call to set_value() does not conflict with anything in the other thread, such as the completion of the constructor or the start of the destructor.
(According to the C++ standard you cannot even make potentially concurrent calls to set_value() and get_future() but that is a defect and should get fixed.)
To give a more precise answer it would be necessary to see exactly what your code is doing.
I am coming from a C# background; as I understand it Swift have automatic memory management like C# does.
An issue in C# that requires the use of “programming patterns” is the timely releasing of resources, as the garbage collector runs at an undefined time, and hence cannot be used to close files, release network connection etc. (Hence IDisposable and the “using” keyword)
How is this dealt with when programming in Swift?
Swift seems to use there same memory management model like Objective-C with ARC enabled.
That means there is no garbage collector. Instead ARC uses reference counting with compiler inserted increment and decrement operations when (strong) references are being set.
The absence of a (threaded) collector means finalization is deterministic in Swift. Objects are deallocated when the last reference goes out of scope.
Swift have the ARC enabled same as Objective-C. You can find the reference from apple documentation.
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-XID_50
Apart from swift's default handing mentioned by NikolaiRuhe, You can use the deinit() methods to force deallocation of objects. You can use this method to remove observers if you have implemented any.
I would like to delete an ovm object (and its children) so that I can recreate it with different configs. Is there a way to do this in OVM?
Currently, when I try to create the object a second time with new, I get the following VCS runtime error:
[CLDEXT] Cannot set 'ap' as a child of 'instance', which already has a child by that name.
I realize that I can simply use a different name to "re-create" the instance, but then I'll still have the old instance sitting around and soaking up memory.
OVM is just a SystemVerilog library. That means that all the rules of SystemVerilog apply to OVM. So, yes, you can use new() with OVM. Sometimes it's preferable to use the factory, and sometimes it's preferable to use new() (that's a topic for a different discussion).
SystemVerilog does not have a delete operator or a destructor like C++. Instead, when you are done with an object you just remove all references to it and the garbage collector will clean up the memory. Here's a quote from the SystemVerilog reference manual (IEEE 1800-2009) section 8.7:
SystemVerilog does not require the complex memory allocation and deallocation of C++. Construction of an object is straightforward; and garbage collection, as in Java, is implicit and automatic. There can be no memory leaks or other subtle behaviors, which are so often the bane of C++ programmers.
It's not entirely true that you cannot have a memory leak. You can forget to remove all references to an object and the garbage collector will not know to pick it up. However, you do not have to worry about memory with the same detail as you do in C++.
The particular error you received with id CLDEXT is from ovm_component class. From the message it appears that you attempted to create two components with the same name and the same parent. Components in OVM are typically static. That is, you create and elaborate them once, usually at time 0, and don't delete or add components after that. Because of this model there are no methods in ovm_component to remove child components. So there really isn't a good way to replace a component once it has been instantiated. By the way, this only applies to components. Other types of objects can be re-allocated.
If you feel that you need to replace a component with a different one after time 0 you should re-think the architecture of your testbench. There are probably betters ways to accomplish what you are trying to do without replacing components.
I have only UVM experience but I think OVM is similar. I would have liked to reply to #Victor Lyuboslavsky's comment but I can't add comments.
The issue is with the name 'ap' which evidently has already been used for a child of 'instance'. Use this code instead.
static int instNum = 0;
instance_ap = my_ovm_extended_class::type_id::create
($sformatf ("ap%0d", instNum), this);
The first time an object is created & the handle assigned to 'instance_ap', the object would have the name 'instance.ap0'. The next time the code executes an object called 'instance.ap1', and so on.
As mentioned by other posters this ought to be done only for non-component objects, and components should be static and must be created during/before the build phase & connected to each other during/before the connect phase.
Try assigning null to the object before calling new again.
Unless I see someone else answer this question, I'd say there is no easy way to deallocate objects in OVM framework.
OVM testbenches are static and created when the testbench is created.
When the environment class is instantiated, it will call new(create), build, connect, end_of_elaboration, start_of_simulation, run and check on all components.
By the end of the environment build phase all components must be created.
By the end of the environment connect phase all components must have their TLM ports connected.
Because of these requirements, you can not change components (or port connections) except for during the phase.
As part of the static nature of the testbench environment, every component must have a unique get_full_name() response. This is because string lookups are used to identify components in the hierarchy.
Assigning an object to null should deallocate memory. If there is no other handle pointing to that memory location, then it should get reclaimed.
I'm using [self retain] to hold an object itself, and [self release] to free it elsewhere. This is very convenient sometimes. But this is actually a reference-loop, or dead-lock, which most garbage-collection systems target to solve. I wonder if objective-c's autorelease pool may find the loops and give me surprises by release the object before reaching [self release]. Is my way encouraged or not? How can I ensure that the garbage-collection, if there, won't be too smart?
This way of working is very discouraged. It looks like you need some pointers on memory management.
Theoretically, an object should live as long as it is useful. Useful objects can easily be spotted: they are directly referenced somewhere on a thread stack, or, if you made a graph of all your objects, reachable through some path linked to an object referenced somewhere on a thread stack. Objects that live "by themselves", without being referenced, cannot be useful, since no thread can reach to them to make them perform something.
This is how a garbage collector works: it traverses your object graph and collects every unreferenced object. Mind you, Objective-C is not always garbage-collected, so some rules had to be established. These are the memory management guidelines for Cocoa.
In short, it is based over the concept of 'ownership'. When you look at the reference count of an object, you immediately know how many other objects depend on it. If an object has a reference count of 3, it means that three other objects need it to work properly (and thus own it). Every time you keep a reference to an object (except in rare conditions), you should call its retain method. And before you drop the reference, you should call its release method.
There are some other importants rule regarding the creation of objects. When you call alloc, copy or mutableCopy, the object you get already has a refcount of 1. In this case, it means the calling code is responsible for releasing the object once it's not required. This can be problematic when you return references to objects: once you return it, in theory, you don't need it anymore, but if you call release on it, it'll be destroyed right away! This is where NSAutoreleasePool objects come in. By calling autorelease on an object, you give up ownership on it (as if you called release), except that the reference is not immediately revoked: instead, it is transferred to the NSAutoreleasePool, that will release it once it receives the release message itself. (Whenever some of your code is called back by the Cocoa framework, you can be assured that an autorelease pool already exists.)
It also means that you do not own objects if you did not call alloc, copy or mutableCopy on them; in other words, if you obtain a reference to such an object otherwise, you don't need to call release on it. If you need to keep around such an object, as usual, call retain on it, and then release when you're done.
Now, if we try to apply this logic to your use case, it stands out as odd. An object cannot logically own itself, as it would mean that it can exist, standalone in memory, without being referenced by a thread. Obviously, if you have the occasion to call release on yourself, it means that one of your methods is being executed; therefore, there's gotta be a reference around for you, so you shouldn't need to retain yourself in the first place. I can't really say with the few details you've given, but you probably need to look into NSAutoreleasePool objects.
If you're using the retain/release memory model, it shouldn't be a problem. Nothing will go looking for your [self retain] and subvert it. That may not be the case, however, if you ever switch over to using garbage collection, where -retain and -release are no-ops.
Here's another thread on SO on the same topic.
I'd reiterate the answer that includes the phrase "overwhelming sense of ickyness." It's not illegal, but it feels like a poor plan unless there's a pretty strong reason. If nothing else, it seems sneaky, and that's never good in code. Do heed the warning in that thread to use -autorelease instead of -release.
In a GC enabled language, when observer subscribes to events of subject, actually subject got a reference of observer.
So before drop an observer, it must un-subscribes first. Other wise, because it's still referenced by subject, it will never be garbage collected.
Normally there are 3 solutions:
Manually un-subscribes
Weak Reference.
Both of them cause other problems.
So usually I don't like to use observer patterns, but I still can not find any replacement for that.
I mean, this pattern describes thing in such a natural way that You could hardly find anything better.
What do you think about it?
In this scenario, you can use finalize() in Java. finalize() is a bad idea when you have to release a resource (like a DB connection) because some outside system is affected. In your case, the object which installed the observer will be GC'd during the runtime of your app and then, finalize() will be called and it can unsubscribe the observer.
Not exactly what you want but someone must decide "it's okay to unsubscribe, now". That either happens when your subject goes away (but it should already kill all observers) or the object which installed the observer.
If your app terminates unexpectedly, well, it doesn't hurt that finalize() might not be called in this case.
If you want to remove an observer you should inform the publisher by unsubscribing, first, otherwise it will try to send out events and depending on how it is written, it could crash the app, quietly ignore the error or remove the observer. But, if you open something, close it; if you subscribe, unsubscribe.
The fact that you are not unsubscribing is a bad design, IMO. Don't blame the pattern for a poor implementation.
The observer pattern works well, but if you want to alleviate some of the issues, you could use AOP for the implementation:
http://www.cin.ufpe.br/~sugarloafplop/final_articles/20_ObserverAspects.pdf
Consider the scenario of an object which counts how often some observable thing changes. There are two types of references to the object: (1) those by entities which are interested in the count; (2) those used by the observable thing(s) which aren't really interested in the the count, but need to update it. The entities which are interested in the count should hold a reference to an object which in turn holds a reference to the one that manages the count. The entities that will have to update the count but aren't really interested in it should just hold references to the second object.
If the first object holds a finalizer, it will be fired when the object goes out of scope. That could trigger the second object to unsubscribe, but it should probably not be unsubscribed directly. Unsubscription would probably require acquiring a lock, and finalizers should not wait on locks. Instead, the finalizer of the first object should probably add that object to a linked list maintained using Interlocked.CompareExchange, and some other thread should periodically poll that list for objects needing unsubscription.
Note, btw: If the first object holds a reference to second object, the latter would be guaranteed to exist when the finalizer for the first object runs, but it would not be guaranteed to be in any particular state. The cleanup thread should not try to do anything with it other than unsubscribe.