Benefit to clearing DataTables - vb.net

I'm wondering if there is a benefit to clearing data tables of information once you are done, is there a noticeable problem if I don't clean the tables out. I know the process of clearing the table out is only one line, but I"m wondering the benefits it's providing, and if the tables will automatically be cleared when I exit a run of the application or will they remain until a computer is restarted?
Example:
Me.dtSet.Tables("ExampleTable").Clear()

Please, see this thread
It essentially states that there is no benefit to disposing of a DataSet / DataTable.
Also:
DataSet and DataTable don't actually have any unmanaged resources, so Dispose() doesn't actually do much. The Dispose() methods in DataSet and DataTable exists ONLY because of side effect of inheritance - in other words, it doesn't actually do anything useful in the finalization.
It turns out that DataSets, DataViews, DataTables suppress finalization in their constructorsc this is why calling Dispose() on them explicitly does nothing.
Presumably, this happens because, as mentioned above, they don’t have unmanaged resources; so despite the fact that MarshalByValueComponent makes allowances for unmanaged resources, these particular implementations don’t have the need and can therefore forgo finalization.
Overview of this Immense Answer:
Without a doubt, Dispose should be called on any Finalizable objects.
DataTables are Finalizable.
Calling Dispose significantly speeds up the reclaiming of memory.
MarshalByValueComponent calls GC.SuppressFinalize(this) in its Dispose() - skipping this means having to wait for dozens if not hundreds of Gen0 collections before memory is reclaimed.
From here, By: Killercam
If those don't fully answer your question, perhaps read this answer.
An important takeaway to your question ->
"Does Dispose() method does not free up the memory & make object as null ??
Dispose and the disposal pattern is not for reclaiming managed memory or "deleting" managed objects (both things you cannot do and what the Garbage Collector is there for), it is for handling the disposal/release of unmanaged resources or other managed resources that have releasable items, such as SqlConnection. It certainly won't null the reference, but may make it unusable from the time of disposal forwards."

Related

Do we need to lock the immutable list in kotlin?

var list = listOf("one", "two", "three")
fun One() {
list.forEach { result ->
/// Does something here
}
}
fun Two() {
list = listOf("four", "five", "six")
}
Can function One() and Two() run simultaneously? Do they need to be protected by locks?
No, you dont need to lock the variable. Even if the function One() still runs while you change the variable, the forEach function is running for the first list. What could happen is that the assignment in Two() happens before the forEach function is called, but the forEach would either loop over one or the other list and not switch due to the assignment
if you had a println(result) in your forEach, your program would output either
one
two
three
or
four
five
six
dependent on if the assignment happens first or the forEach method is started.
what will NOT happen is something like
one
two
five
six
Can function One() and Two() run simultaneously?
There are two ways that that could happen:
One of those functions could call the other.  This could happen directly (where the code represented by // Does something here in One()⁽¹⁾ explicitly calls Two()), or indirectly (it could call something else which ends up calling Two() — or maybe the list property has a custom setter which does something that calls One()).
One thread could be running One() while a different thread is running Two().  This could happen if your program launches a new thread directly, or a library or framework could do so.  For example, GUI frameworks tend to have one thread for dispatching events, and others for doing work that could take time; and web server frameworks tend to use different threads for servicing different requests.
If neither of those could apply, then there would be no opportunity for the functions to run simultaneously.
Do they need to be protected by locks?
If there's any possibility of them being run on multiple threads, then yes, they need to be protected somehow.
99.999% of the time, the code would do exactly what you'd expect; you'd either see the old list or the new one.  However, there's a tiny but non-zero chance that it would behave strangely — anything from giving slightly wrong results to crashing.  (The risk depends on things like the OS, CPU/cache topology, and how heavily loaded the system is.)
Explaining exactly why is hard, though, because at a low level the Java Virtual Machine⁽²⁾ does an awful lot of stuff that you don't see.  In particular, to improve performance it can re-order operations within certain limits, as long as the end result is the same — as seen from that thread.  Things may look very different from other threads — which can make it really hard to reason about multi-threaded code!
Let me try to describe one possible scenario…
Suppose Thread A is running One() on one CPU core, and Thread B is running Two() on another core, and that each core has its own cache memory.⁽³⁾
Thread B will create a List instance (holding references to strings from the constant pool), and assign it to the list property; both the object and the property are likely to be written to its cache first.  Those cache lines will then get flushed back to main memory — but there's no guarantee about when, nor about the order in which that happens.  Suppose the list reference gets flushed first; at that point, main memory will have the new list reference pointing to a fresh area of memory where the new object will go — but since the new object itself hasn't been flushed yet, who knows what's there now?
So if Thread A starts running One() at that precise moment, it will get the new list reference⁽⁴⁾, but when it tries to iterate through the list, it won't see the new strings.  It might see the initial (empty) state of the list object before it was constructed, or part-way through construction⁽⁵⁾.  (I don't know whether it's possible for it to see any of the values that were in those memory locations before the list was created; if so, those might represent an entirely different type of object, or even not a valid object at all, which would be likely to cause an exception or error of some kind.)
In any case, if multiple threads are involved, it's possible for one to see list holding neither the original list nor the new one.
So, if you want your code to be robust and not fail occasionally⁽⁶⁾, then you have to protect against such concurrency issues.
Using #Synchronized and #Volatile is traditional, as is using explicit locks.  (In this particular case, I think that making list volatile would fix the problem.)
But those low-level constructs are fiddly and hard to use well; luckily, in many situations there are better options.  The example in this question has been simplified too much to judge what might work well (that's the down-side of minimal examples!), but work queues, actors, executors, latches, semaphores, and of course Kotlin's coroutines are all useful abstractions for handling concurrency more safely.
Ultimately, concurrency is a hard topic, with a lot of gotchas and things that don't behave as you'd expect.
There are many source of further information, such as:
These other questions cover some of the issues.
Chapter 17: Threads And Locks from the Java Language Specification is the ultimate reference on how the JVM behaves.  In particular, it describes what's needed to ensure a happens-before relationship that will ensure full visibility.
Oracle has a tutorial on concurrency in Java; much of this applies to Kotlin too.
The java.util.concurrent package has many useful classes, and its summary discusses some of these issues.
Concurrent Programming In Java: Design Principles And Patterns by Doug Lea was at one time the best guide to handling concurrency, and these excerpts discuss the Java memory model.
Wikipedia also covers the Java memory model
(1) According to Kotlin coding conventions, function names should start with a lower-case letter; that makes them easier to distinguish from class/object names.
(2) In this answer I'm assuming Kotlin/JVM.  Similar risks are likely apply to other platforms too, though the details differ.
(3) This is of course a simplification; there may be multiple levels of caching, some of which may be shared between cores/processors; and some systems have hardware which tries to ensure that the caches are consistent…
(4) References themselves are atomic, so a thread will either see the old reference or the new one — it can't see a bit-pattern comprising parts of the old and new ones, pointing somewhere completely random.  So that's one problem we don't have!
(5) Although the reference is immutable, the object gets mutated during construction, so it might be in an inconsistent state.
(6) And the more heavily loaded your system is, the more likely it is for concurrency issues to occur, which means that things will probably fail at the worst possible time!

Vulkan: Any downsides to creating pipelines, command-buffers, etc one at a time?

Some Vulkan objects (eg vkPipelines, vkCommandBuffers) are able to be created/allocated in arrays (using size + pointer parameters). At a glance, this appears to be done to make it easier to code using common usage patterns. But in some cases (eg: when creating a C++ RAII wrapper), it's nicer to create them one at a time. It is, of course, simple to achieve this.
However, I'm wondering whether there are any significant downsides to doing this?
(I guess this may vary depending on the actual object type being created - but I didn't think it'd be a good idea to ask the same question for each object)
Assume that, in both cases, objects are likely to be created in a first-created-last-destroyed manner, and that - while the objects are individually created and destroyed - this will likely happen in a loop.
Also note:
vkCommandBuffers are also deallocated in arrays.
vkPipelines are destroyed individually.
Are there any reasons I should modify my RAII wrapper to allow for array-based creation/destruction? For example, will it save memory (significantly)? Will single-creation reduce performance?
Remember that vkPipeline creation does not require external synchronization. That means that the process is going to handle its own mutexes and so forth. As such, it makes sense to avoid locking those internal mutexes whenever possible.
Also, the process is slow. So being able to batch it up and execute it into another thread is very useful.
Command buffer creation doesn't have either of these concerns. So there, you should feel free to allocate whatever CBs you need. However, multiple creation will never harm performance, and it may help it. So there's no reason to avoid it.
Vulkan is an API designed around modern graphics hardware. If you know you want to create a certain number of objects up front, you should use the batch functions if they exist, as the driver may be able to optimize creation/allocation, resulting in potentially better performance.
There may (or may not) be better performance (depending on driver and the type of your workload). But there is obviously potential for better performance.
If you create one or ten command buffers in you application then it does not matter.
For most cases it will be like less than 5 %. So if you do not care about that (e.g. your application already runs 500 FPS), then it does not matter.
Then again, C++ is a versatile language. I think this is a non-problem. You would simply have a static member function or a class that would construct/initialize N objects (there's probably a pattern name for that).
The destruction may be trickier. You can again have static member function that would destroy N objects. But it would not be called automatically and it is annoying to have null/husk objects around. And the destructor would still be called on VK_NULL_HANDLE. There is also a problem, that a pool reset or destruction would invalidate all the command buffer C++ objects, so there's probably no way to do it cleanly/simply.

Are there any alternative concepts for handling unmanaged resources in garbage collected languages?

Garbage collected object oriented programming languages reclaim unused memory automatically, but all other kinds of resources (i.e. files, sockets...) still require manual release since finalizers cannot be trusted to run in time (or at all).
Therefore such resource objects usually provide some kind of "close"- or "dispose"-method/pattern, which can be problematic for a number of reasons:
Dispose has to be called manually which may pose problems in cases when it is not clear when the resource has to be released (similar problem as with manual memory management)
The disposable-pattern is somewhat "viral", since each class containing a disposable resource must be made disposable as well in order to guarantee correct resource cleanup
An addition of a disposable member to a class, requiring the class to become disposable as well, changes the interface and the usage patterns of the class, thus breaking encapsulation
The disposable-pattern creates problems with inheritance, i.e. when a derived class is disposable, while the base class isn't
So, are there any alternative concepts/approaches for properly releasing such resources? Any papers/research in that direction?
One approach (in languages that support it) is to manually trigger a garbage collection event to cause finalizers to run. However, some languages (like Java) do not provide a reliable mechanism for doing so.

When a form disposed, are all form data and datasets also disposed?

As the title, When a form disposed, are all form data and datasets also disposed?
Example:
Dim C As New Commands
C.ShowDialog
C.Disopse()
So C form contains datasets and oledbconnections and more objects that were not disposed . If not, what is the best method to free memory and release all resources?
As with other .NET objects, you cannot guarantee datasets will be disposed when the form is disposed. This is because .NET constantly monitors whether or not there are active pointers to the objects in memory. If no links were found, it frees up memory allocated to the object. Such process is called garbage collection - a feature of CLR.
Problem is that you can have a variable that points to the same data set, on another form, class, and even in another project. You can spawn as many of those variables as you want. As a developer, you must work out a strategy to control who consumes your objects and how. Otherwise you will never know if at any given moment a particular dataset was actually disposed.
Using clause helps control disposal of objects, but it's not the ultimate solution. You can still get in trouble if you don't know what you are doing. And sometimes you would need to pass undisposed connection objects to other functions on purpose, for more granular control over data processing.
A form's .Dispose() method is there to handle the otherwise-unmanaged GDI resources used by the form. Since that method doesn't know anything else about what you might have added, you can't be sure that items such as datasets are disposed as well.
The best you can hope for is that since Dispose()-ing a form is also highly indicative that the form is about to become eligible for garbage collection, your other resources are also likely about to become eligible for garbage collection. If the Dispose() and finalizer patterns for those types was implemented correctly, then it is highly likely that your other items will be disposed soon. Just how soon is impossible to say... that's why the dispose pattern exists: for those times when you need to sure an unmanaged resource is cleaned up right away.
The way I would recommend freeing any additional resources is to override the normal Windows Forms Dispose() method. Your new implementation of the Dispose() method will call the base implementation using the MyBase keyword, and also call Dispose() for any IDisposable members of your form. This way, the form will still work correctly as part of a Using block.

Should a managed class that wraps a DirectSound interface be IDisposable?

I'm writing a managed wrapper around DirectSound. (It's a simple partial wrapper that solves my specific problem and nothing more. Don't tell me about NAudio or whatever.) Should a managed class that wraps IDirectSound8 be IDisposable and why? Same question about IDirectSoundBuffer8.
Technically: yes. Practically: no. IDirectSound8 is a COM interface, they are very conveniently wrapped in .NET with a interop library. An RCW. That RCW manages the reference counts on the underlying COM coclass object. An RCW does not implement IDisposable, even though it very much hangs on to an unmanaged resource.
The reason it doesn't is because it is almost impossible to implement IDisposable correctly. A COM coclass implements multiple interfaces, creating one adds to the reference count. You would have to be 100% sure that all of those interface pointers are no longer in use before a dispose would be safe. That's very hard to do, those pointers get created in unexpected ways. Like using an indexed property of one of the interfaces, the intermediate interface pointer is never visible in your code.
This is not a real problem, the garbage collector takes care of the reference counts, the finalizer gets the job done. It is just that it takes a bit longer for the object to be released. Standard GC behavior. Unfortunately out-of-process COM servers have observable side-effects, programmers tend to get annoyed when the process doesn't disappear from the TaskMgr processes list at the instant their code stops using the interfaces. Many, many "Excel/Word doesn't quit" questions here and at the forums.
If you want to implement it anyway then you can do so by calling Marshal.FinalReleaseComObject() in your Dispose() implementation. Just beware of the significantly increased risk for failure, getting that call wrong produces very hard to diagnose failure. Not quite unlike deleting an object in native code and still having a pointer to it. If it is actually a "heavy" object that must be released instantly then GC.Collect() + GC.WaitForPendingFinalizers() gets the job done too with much less risk of getting it wrong. With side-effects of course.