|
You should show us the basic code (how you get the interface pointers). In general, you have to call Release() for each kind of interface object when not used anymore. This applies to all pointers retrieved by calling for example CoCreateInstance and QueryInterface .
If a called function is allocating memory internally and returning that to the caller it should be documented. The documentation should then include how to free the memory (e.g. with CoTaskMemFree ).
|
|
|
|
|
Thanks. Please find the code
VARIANT Attributessets;
VariantInit(&Attributessets);
m_OcxObj->GetAttributes(ID, &Attributessets);
Attributessets.pdispVal->Release()
|
|
|
|
|
How did you know that the memory is not released and how do you determine the memory used by your application?
You have to know how the memory is managed which requires knowing the used allocation method. Most memory is allocated in the default per-process heap. If this heap is used up, it is resized by requesting more memory from the operating system. But it will not shrink (at least not immediately) when freeing memory (which occurs when the reference count reaches zero upon releasing). It is finally returned to the operating system when the process terminates. As a result, you might see increasing process memory usage while the process is running.
There is a rather old article that explains the heap managment for Windows: Heap: Pleasures and Pains[^].
In your case of a VARIANT set by a OCX function you have no control over the memory management and even did not know which allocation method is used. If an object must be released depends on the data stored in the VARIANT and should be part of the documentation. In your case of a pdispVal , the OCX control might for example increase the reference count for the dispatch when calling GetAttributes() . Then it will be released finally when releasing the OCX control or you have to call Release() which should be again mentioned in the documentation. It depends also on what you are doing with the interface. If you are calling dispatch functions that increase the reference count, you have to call Release() the same times.
|
|
|
|
|
Thanks for the information provided.
For the question:
How did you know that the memory is not released and how do you determine the memory used by your application?
we call this Getattributes() method in a for loop. for every iteration, it takes around 8 KB memory and finally at the end of this loop process memory shoots up by 50 MB,which is unwanted for us.
we did call Release()method on the pDispval once. but did not work..
i will once again explain the worflow and my questions to give more clarification..
First we get the attributes from the OCX interface using GetAttributes() and we get variant with Pdispvalue.... Does OCX increase the refernce count of Pdispvalue to one here ?
Then we attach this pdispval to the OledispatchdriverObject using AttachDispatch()...Does the refrence count go to two ?
OCX gets destroyed only when main application ends but increase in the memory effects our application.
Do i need to call Release() twice on the pDispval to make it clear ? Does memory gets freed at the end of second Release() call or is it the OCX destruction that clears it.
|
|
|
|
|
Member 10253026 wrote: First we get the attributes from the OCX interface using GetAttributes() and we get variant with Pdispvalue.... Does OCX increase the refernce count of Pdispvalue to one here ? This should be part of the OCX documentation. I guess that the reference count is incremented.
Quote: Then we attach this pdispval to the OledispatchdriverObject using AttachDispatch()...Does the reference count go to two ?
AttachDispatch() will increment the reference count. So you have to call Release() or set bAutoRelease . But when using AttachDispatch() your OleDispatchDriver object will be the owner of the interface. So you should not use the pDispVal member of the VARIANT afterwards anymore (set it to NULL to avoid using it).
Memory is only freed when the reference count becomes zero when calling Release() .
I suggest to check the return value when calling Release() . Then you will know when memory is freed. To check the actual reference count without releasing, just call AddRef() and Release() .
|
|
|
|
|
Member 10253026 wrote: Can some one help me in deleting the memory in my application created by that function in ocx.?
If your windows application allocates 1GB of RAM... then properly releases it... Yes; the operating system is very lazy in returning that memory back to the system. This is by design. You should not do anything and allow the OS to manage memory. The OS is very good at this.
In theory you should be able to do:
SetProcessWorkingSetSize(-1,-1);
or
EmptyWorkingSet(YourPID);
This will force the OS to release all unused pages assigned to your application. But trust me... this is not necessary and will most likely do more harm than good.
Best Wishes,
-David Delaune
|
|
|
|
|
Why is it that in the following program, the value of newCount that prints at the end is 10, as I would expect, while the value of newTime.count() that prints is -3689348814741910324?
#include "stdafx.h"
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <chrono>
#include <fstream>
#include <iostream>
namespace boost
{
namespace serialization
{
template<class Archive>
void serialize(Archive&ar, std::chrono::nanoseconds&time, const unsigned int version)
{
long long count{ time.count() };
ar&count;
}
}
}
int main()
{
std::chrono::nanoseconds time(10);
long long count = time.count();
{
std::ofstream saveFile("filename");
boost::archive::text_oarchive boostOutputArchieve(saveFile);
boostOutputArchieve << time;
boostOutputArchieve << count;
}
std::chrono::nanoseconds newTime;
long long newCount;
{
std::ifstream loadFile("filename");
boost::archive::text_iarchive boostInputArchieve(loadFile);
boostInputArchieve >> newTime;
boostInputArchieve >> newCount;
}
std::cout << newTime.count() << '\n' << newCount << '\n';
return 0;
}
I would have thought setting up the serialize() overload for nanoseconds to serialize the tick count and using that would have the same result as serializing the tick count directly.
|
|
|
|
|
I've realized that -3689348814741910324 is the value uninitialized variables get set to when debugging, so...does that mean that the line
boostInputArchieve >> newTime; is currently doing nothing?
|
|
|
|
|
Can't you debug this code?
|
|
|
|
|
If I knew what I was looking for. It's entirely possible that my debugging skills are lacking.
|
|
|
|
|
Apparently the fact that the serialization requires (as far as I can tell) the extra step of reading the count into a variable breaks the symmetry between save and load operations, so I have to overload them individually rather than handling both in a serialize() overload. This is what I've tried:
namespace boost
{
namespace serialization
{
template<class Archive>
void save(Archive&ar, const std::chrono::nanoseconds&time, const unsigned int version)
{
long long count{ time.count() };
ar&count;
}
template<class Archive>
void load(Archive&ar, std::chrono::nanoseconds&time, const unsigned int version)
{
long long count;
ar&count;
time = std::chrono::nanoseconds(count);
}
}
}
BOOST_SERIALIZATION_SPLIT_FREE(std::chrono::nanoseconds)
It seems to work, though I'm not confident that this is the way it's supposed to be done.
|
|
|
|
|
Vaguely years ago I recall being able to do this, but I'm having a senior moment.
I have a program, lets call it test.exe, that is launched by another program that starts as a service. Is there a way to configure VS2015 to launch and run test.exe in the debugger?
Charlie Gilley
<italic>Stuck in a dysfunctional matrix from which I must escape...
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
Hi,
You are probably looking for the 'Image File Execution' registry key:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
If you want to avoid manually editing registry keys... you can download GFlags[^] to enable automatic debugger attachment. All it really does is set those registry keys for you.
Best Wishes,
-David Delaune
|
|
|
|
|
ooookay, I didn't expect that answer. Totally new to me, I'll look into it.
Charlie Gilley
<italic>Stuck in a dysfunctional matrix from which I must escape...
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
charlieg wrote: ooookay, I didn't expect that answer.
Liquid Nitrogen. It's what I use for branding my cattle[^].
charlieg wrote: Totally new to me
I highly recommend learning how to use all of the debugging tools.
Best Wishes,
-David Delaune
|
|
|
|
|
Lol, just perused the gflags area. Might be a little heavy for what I need, but very interesting items.
Thanks
Charlie Gilley
<italic>Stuck in a dysfunctional matrix from which I must escape...
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
charlieg wrote: Might be a little heavy for what I need, but very interesting items.
Two thoughts:
1.) If you actually want to debug an error occuring when ProgramB is launched from ProgramA. There is no other way.
2.) If your question was worded incorrectly and you just simply need to debug ProgramB then just attach a debugger to it.
Best Wishes,
-David Delaune
|
|
|
|
|
Assuming that test.exe is a Debug version, or you have the source, you can just launch it directly from Visual Studio. But if it is not a Debug version you will not get much useful information from the debugger.
[edit]
Also you can attach the debugger to a running process.
[/edit]
|
|
|
|
|
I have the debug code, so this approach might work. I normally live in the embedded world, and the magic of attaching to running processes to debug is mostly a foreign concept.
I hope this works....
Charlie Gilley
<italic>Stuck in a dysfunctional matrix from which I must escape...
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
It helps to have all the source code also, and/or the .PDB file with the debug information, so you can see proper details of what is going on. Sounds complicated, but it's really useful.
|
|
|
|
|
Hi
I am getting a local variable overlayed now I am beginning to think it maybe because of the way I declared it
for example void process_trace()
{
char BASSM[2] = {0X0C, 0XEF};
This is still considered a local variable even though its assigned value since I didn't use the key word static
So I guess on entry to the function the complier re-initializes the value everytime
I guess I am thinking since this variable is some how being overlayed and I am not changing the value I should make it static
Thanks
|
|
|
|
|
Where is it getting overlayed?
|
|
|
|
|
I made a DATA breakpoint in Visual Studio and the overlay was some where deep in Windows in ntdll I did a Call Stack and it wasn't in the function that BASSM was declared
truth is at the very least since the value of BASSM is not being changed I should qualify it with a const to save compiler the trouble of initializing it every time
|
|
|
|
|
No, you should first find out where it is being overwritten and why. This error tells you that you have a bug in your code, so rather than try to hide it, you need to fix it. But without seeing more of your code it is difficult to guess what might be the cause.
|
|
|
|
|
I could post all the code in the function but I don't think that would help
I'll spend tonite trying to figure it and regardless I'll re-declare BASSM as const
that still shouldn't stop the bug as its still a local stack variable
thanks
|
|
|
|