Windows UMDF CComPtr IWDFMemory does not get freed - memory-leaks

In my UMDF driver i have a IWDFMemory packed inside a CComPtr
CComPtr<IWDFMemory> memory;
The documentation of CComPtr says, If a CComPtr object gets out of scope, it gets automagically freed. That means this code should not create any memory leaks:
void main()
{
CComPtr<IWDFDriver> driver = /*driver*/;
/*
driver initialisation
*/
{
// new scope starts here
CComPtr<IWDFMemory> memory = NULL;
driver->CreateWdfMemory(0x1000000, NULL, NULL, &memory);
// At this point 16MB memory have been allocated.
// I can verify this by the task manager.
// scope ends here
}
// If I understand right the memory I allocated in previous scope should already
// be freed at this point. But in the task manager I still can see the 16 MB
// memory used by the process.
}
Also if I manually assign NULL to memory or call memory.Release() before scope end the memory does not get freed. I am wondering what is happening here?

According to MSDN:
If NULL is specified in the pParentObject parameter, the driver object
becomes the default parent object for the newly created memory object.
If a UMDF driver creates a memory object that the driver uses with a
specific device object, request object, or other framework object, the
driver should set the memory object's parent object appropriately.
When the parent object is deleted, the memory object and its buffer
are deleted.
Since you do indeed pass NULL, the memory won't be released until the CComPtr<IWDFDriver> object is released.

Related

Memory leak when using chunk/complete callbacks and worker

I pass the options as
{
...
chunk: () => this.chunk(results,parser),
complete: () => this.complete(results,parser)
}
And this doesn't leak memory when worker is false but leaks memory when worker is true. The leak is because the closures are somehow retained. Looking at the papaparse code it seems that the callback functions are copied to the worker object as worker.userXYZ functions. However, at the end the worker is terminated and deleted. So, ideally the closures should have been freed up too.
Is there any extra step required when using the worker option so the memory is freed up properly?
This seems to be related to Worker objects are not freed
I had a large object held up via the chunk function which refers to this. So, by setting the reference to null in complete freed up the memory.

Meaning of ref class and gcnew

I am not clear about the usage of keywords gcnew and ref class. usually in C++ when we use keyword new for creating an object that time only the memory for the class allocated in Heap. As per I read about VC++ ref class when we use this token to create class then the memory for the class allocated in Heap before the object creation. is it true? if suppose it is to be true then what is the usage of gcnew. is gcnew does anything with reference count?
What is difference in below Handler creation statements
1)<class Name> ^<handler> = gcnew <class Name>;
2)<class Name> <handler>;
I know the first one allocates the memory in heap for that class. what about Second one, Usually in C++ if I create handler like this then the memory for that class is allocated in the stack, As per I read in C++/CLI programming when I creating a class using the token ref class then the memory for the class allocated in heap. I want to know whether the Second handler creation statement also creates the memory in heap.

Why does finalize() execute only after new object is created, but not after gc() is invoked?

Shouldn't finalize() execute immediately when gc() is called? The order of output result is a little unconvincing.
class Test
{
int x = 100;
int y = 115;
protected void finalize()
{System.out.println("Resource Deallocation is completed");}
}
class DelObj
{
public static void main(String arg[])
{
Test t1 = new Test();
System.out.println("Values are "+t1.x+", "+t1.y+"\nObject refered by t1 is at location: "+t1);
t1 = null; // dereferencing
System.gc(); // explicitly calling
Test t2= new Test();
System.out.println("Values are "+t2.x+", "+t2.y+"\nObject refered by t2 is at location: "+t2);
}
}
Got the execution result of finalize() after a new object is created, referred by t2:
D:\JavaEx>java DelObj
Values are 100, 115
Object refered by t1 is at location: Test#6bbc4459
Values are 100, 115
Object refered by t2 is at location: Test#2a9931f5
Resource Deallocation is completed
Calling System.gc() only provides a hint to the JVM, but does not guaranty that an actual garbage collection will happen.
However, the bigger problem with your expectation is that garbage collection is not the same as finalization.
Referring to the Java 6 documentation, System.gc() states:
Runs the garbage collector.
Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. …
Compare to System.runFinalization():
Runs the finalization methods of any objects pending finalization.
Calling this method suggests that the Java Virtual Machine expend effort toward running the finalize methods of objects that have been found to be discarded but whose finalize methods have not yet been run. …
So there can be “pending finalization”, resp. “objects that have been found to be discarded but whose finalize methods have not yet been run”.
Unfortunately, Java 6’s documentation of finalize() starts with the misleading sentence:
Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.
whereas garbage collection and finalization are two different things, hence, the finalize() method is not called by the garbage collector. But note that the subsequent documentation says:
The Java programming language does not guarantee which thread will invoke the finalize method for any given object.
So when you say “The order of output result is a little unconvincing”, recall that we’re talking about multi-threading here, so in absence of additional synchronization, the order is outside your control.
The Java Language Specification even says:
The Java programming language does not specify how soon a finalizer will be invoked, except to say that it will happen before the storage for the object is reused.
and later on
The Java programming language imposes no ordering on finalize method calls. Finalizers may be called in any order, or even concurrently.
In practice, the garbage collector will only enqueue objects needing finalization, while one or more finalizer threads poll the queue and execute the finalize() methods. When all finalizer threads are busy executing particular finalize() methods, the queue of objects needing finalization may grow arbitrary long.
Note that modern JVMs contain an optimization for those classes not having a dedicated finalize() method, i.e. inherit the method from Object or just have an empty method. Instances of these classes, the majority of all objects, skip this finalization step and their space gets reclaimed immediately.
So if you added a finalize() method just to find out when the object gets garbage collected, it’s the very presence of that finalize() method which slows down the process of the memory reclamation.
So better refer to the JDK 11 version of finalize():
Deprecated.
The finalization mechanism is inherently problematic. Finalization can lead to performance issues, deadlocks, and hangs. Errors in finalizers can lead to resource leaks; there is no way to cancel finalization if it is no longer necessary; and no ordering is specified among calls to finalize methods of different objects. Furthermore, there are no guarantees regarding the timing of finalization. The finalize method might be called on a finalizable object only after an indefinite delay, if at all. Classes whose instances hold non-heap resources should provide a method to enable explicit release of those resources, and they should also implement AutoCloseable if appropriate. The Cleaner and PhantomReference provide more flexible and efficient ways to release resources when an object becomes unreachable.
So when your object does not contain a non-memory resource, hence, doesn’t actually need finalization, you can use
class Test
{
int x = 100;
int y = 115;
}
class DelObj
{
public static void main(String[] arg)
{
Test t1 = new Test();
System.out.println("Values are "+t1.x+", "+t1.y+"\nObject refered by t1 is at location: "+t1);
WeakReference<Test> ref = new WeakReference<Test>(t1);
t1 = null; // dereferencing
System.gc(); // explicitly calling
if(ref.get() == null) System.out.println("Object deallocation is completed");
else System.out.println("Not collected");
Test t2= new Test();
System.out.println("Values are "+t2.x+", "+t2.y+"\nObject refered by t2 is at location: "+t2);
}
}
The System.gc() call still is only a hint, but you will find your object being collected afterwards in most practical cases. Note that the hash code printed for the objects, like with Test#67f1fba0 has nothing to do with memory locations; that’s a tenacious myth. The patterns behind object memory addresses is often unsuitable for hashing, further most modern JVMs can move objects to different memory locations during their lifetime, whereas the identity hash code is guaranteed to stay the same.

freeing up memory of Buffer instance in Node.js

node comes with abundance of method to create Buffers, but I haven't found one that dealocated the allocated piece of memory.
Do I just set buffer to null when I am done using it and let garbage collection kick in?
var buffer = new Buffer("pls dont null me");
buffer = null;
You should not care about it.
When you stop using the variable, the garbage collector will collect.
Just in case, its ok if you want to set null.
See the buffer documentation in the Node.js site.

Any memory leak by delete and create same object several times

It may be just a memory leak question. For those not familiar with WinSCP, skip ahead to question.
I am using .net assembly of WinSCP in a C++/CLI program. My program will read in a schedule file. The file instructs the program to transfer files from various locations. Some transfers could come from the same server, so my program should close the existing connection if it is a new server. If the server is the same, keep the connection to use.
As there is no Session::Close(), the document recommends to use Session::Dispose() (Refer to Session.Dispose() Documentation.) Yet when I compile, I see error message saying:
'Dispose' is not a member of 'WinSCP::Session'
Eventually I use delete session. Part of my program will then roughly look like:
void Transfer(String ^ sAction, String ^ sMode,
String ^ sSource_Server, String ^ sSource_Path,
String ^ sDest_Server, String ^ sDest_Path,
bool bDelDir, bool bDelFile )
{
if ((GlobalClass::g_sFtp_Server != sSource_Server && sAction == "G")
|| (GloblaClass::g_sFtp_Server != sDest_Server && sAction == "P"))
{
// Close existing connection first.
if (GlobalClass::g_sftpSession != nullptr)
delete GlobalClass::g_sftpSession;
if (GlobalClass::g_sftpSessionOptions != nullptr)
// Reuse the object
GlobalClass::g_sftpSessionOptions->HostName = sSource_Server;
else
{
// Recreate object and fill in detail
GlobalClass::g_sftpSessionOptions = gcnew WinSCP::SessionOptions();
GlobalClass::g_sftpSessionOptions->Protocol ....
GlobalClass::g_sftpSessionOptions->HostName ....
}
// Create new session
GlobalClass::g_sftpSession = gcnew WinSCP::Session();
GlobalClass::g_sftpSession->Open(GlobalClass::g_sftpSessionOptions);
// Set GlobalClass::g_sFtp_Server
}
// Transfer files accordingly...
}
【Question】: Will there be any memory leak by deleting the object (delete GlobalClass::g_sftpSession) and create it again (GlobalClass::g_sftpSession = gcnew WinSCP::Session()) many times per minute?
From several .net resources I have read, the delete object action will mark the object to be garbage collected. When will it be done? It is entirely up to the gc mechanism. So if my program has to make connections to several sites, it has to do that delete and create several times. By the program finishes (usually in less than 1 minute), can I count on the garbage collection mechanism to clean out all memory? Reason I ask is my program will run every minute. If there is memory leak each time program is run, my machine will be out of memory very soon.
The WinSCP .NET assembly Session class has the Dispose method. Though it's probably hidden by C++/CLI. You call the Dispose indirectly using the delete. See How do you dispose of an IDisposable in Managed C++ and Calling C++/CLI delete on C# object.
Generally, even if you do not, the garbage collector will do this for you (in an unpredictable moment), as you do not keep reference to old sessions. But it definitely won't let your machine run out of memory.
On the other hand, you NEED to call the Dispose (the delete) to close the unused sessions anyway, otherwise you may run out of allowed connections to the servers (or even exhaust servers' resources).
If you want to check, if and when the session is disposed, set the Session.DebugLogPath and search a log for an entry like:
[2014-04-23 08:08:50.756Z] [000a] Session.Dispose entering
Your question whether there's a chance for a memory leak, when a program finishes is irrelevant. Any memory allocated by a process is released by an operating system when the process finishes. No matter what leak/bug/anything is in the program itself. See also Does the heap get freed when the program exits? Anyway, I believe your code does not leak memory.

Resources