Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

MTS "Out Of Memory" - Error: 4104 - Context Wrapper

Status
Not open for further replies.

cradster

Programmer
Sep 9, 2000
7
GB
I have created and compiled up several ActiveX DLL which have been succesfully registered with MTS, the objects can then be succesfully instanciated from ASP (JavaScript) pages. Every now and then I get an "Out Of Memory" error. I have checked the Windows NT Event Viewer and found that its to be Error 4104, Context Wrapper. I have the latest version of MDAC (My ActiveX DLL's do allot of Informix DB stuff) and Service pack 6a has been installed, still the Problem persists. Does anybody know what the source of this problem is? and if so, how to resolve it? [sig][/sig]
 

I had nightmares about this error message. I finally got it fixed but I'm not sure if it is applicable in your situation.

Within the DLL some objects were creating other objects and I was using the New keyword:

Set objA = New MyObject

Objects created with the New keyword are not created under the "umbrella" of MTS' Context wrapper; thus, MTS does not manage their memory. I changed the code to:

Set objA = CreateObject("MyApp.MyObject")

Also, Make sure that when you're done with an object, whether it is created from the DLL itself or from another app, you free the memory allocated to it by doing:

Set objA = Nothing

Are you implementing ObjectControl? [sig][/sig]
 
You are not alone in fighting this issue. I found these suggestions in researching the same issue:

MTS Tips:

Unattended Execution
Set Unattended Execution in project properties. Checking this box will ensure that no user interaction is required with the object. For example, MsgBox calls will be logged to the event log rather than popping up a box on your MTS server and waiting for someone to happen by and click "OK". You should always check Unattended Execution in your MTS COM objects.

Retained in Memory
The Retained in Memory checkbox will become available within the Project Properties dialog box once you have checked Unattended Execution. You should also check this box. According to Microsoft, "If this box is unchecked, DLLs may be released in an unexpected order that may cause your app to crash on shutdown, interrupting normal cleanup procedures and producing ambiguous errors as well as some undefined behaviors". Not good.

Here's Microsoft's response on the matter I found on another message board:

[Troy Cambra:]

"All VB components that run in MTS or IIS must have the "Unattended Execution" and "Retain in Memory" settings checked. We (Microsoft) have been very remiss in not making this more known. The "Retain in Memory" setting has been documented as merely a performance improvement setting when in fact, it only provides a minimal performance improvement. The real benefit is in reliability. You can not have reliability without it. Try this test:

Create a simple do nothing MTS component without those settings (just return a string or something).
Create a simple client to call the do nothing component repeatedly in a loop (Create/Use/Release).
Install the component in MTS.
Run the test
Open Perfmon or Task Manager and watch the handle count in that MTX process.
It should be leaking handles like a sieve. This is just one symptom of the underlying problem which is that the VB project and thread construction/destruction code is not threadsafe or stable under stress. This problem has been around forever. You might be familiar with the VB5 clsEmpty fix (Q186273). This is the same problem. The "Retain in Memory" setting in VB6 just does what the clsEmpty workaround did in VB5 - only a little neater. We have finally put out a KB on this issue, but it is still incomplete in it’s description of the problem and the symptoms. It is KB article Q241896." [sig][/sig]
 

rayploski,

I tried your example, once with the "Retained in Memory" and once without it. I did not see any difference in the Handle Count. [sig][/sig]
 
I have tried all of the above and had no success, but I have managed to work around the problem by using a System DSN as opposed to a Connection String. My ADO Connection object within my ActiveX DLL's were using a Connection string, instead I created a System DSN and set my Connection String to &quot;DSN=<dsn_name>&quot;, I don't consider this to be a fix but more of a workaround. I have stress tested the server thats running the ActiveX DLL's with a self refreshing ASP page which was being called from 34 different browser sessions, it all worked fine and the work load on the Server appeared to be minimal.

If switching from a connection string to a DSN spreads any more light on the problem then please could someone let me know.

PS. I thought that the DSN may have worked because it was connection pooling, so I turned this option off for the ODBC driver I was using and the DLL's still worked fine, so I don't think that the problem lies with connection pooling. [sig][/sig]
 
I am having the same problem, but with no self-developped components.
I have an NT server with Oracle8i, IIS, and Crystal Reports 8.
IIS/ASP accesses the database through a DSN-less connection (though only recently, before it was a system DSN) and CR8 accesses it through a system DSN.

It seems that the web publishing server crashes (leaving an MTS-4104 error in the event log) only if CR8 is used by a client.
However, this is by no means systematic.
Do you have any suggestions as to how to solve this?
I have checked all the newsgroups and web sites I could find, and this thread is the only thing so far which seems to correspond to my problem.
 
Yes, I believe that AS400 is correct. I think what is happening is that you (and me as well) are having memory leaks due to relying on MTS to clean up after itself properly (i.e., ensuring that objects you create are set to nothing when you are done with them), especially if you use NEW instead of CreateObject.

Tom
 
Opps.. I mean VB400 :)

Anyways, here's a quote from MSDN:

&quot;In a component designed for use with Microsoft Transaction Server, an instance of any of your project's externally creatable classes created with the New operator will be unknown to Microsoft Transaction Server. Objects that will be used with Microsoft Transaction Server must be created using CreateObject.&quot;

Therefore, I believe that the objects created with New are the ones causing memory leaks...

Tom

 
I am getting the same &quot;Out Of Memory&quot; error (4104 - Context Wrapper). I am creating components in VC++ and have successfully registered them under MTS. I am instantiating them from ASP using &quot;CreateObject&quot; & setting the object to &quot;Nothing&quot; after use...but I am still getting this error...I have NTServer (IIS) & Oracle8i.

Please help ASAP...

 
A few points that might help (NT4SP3):

The CR8 engine is a single-threading DLL. I am not sure what the impact of that is, but the developer help makes a point of stating it.

The Oracle client-side products do something to MDAC that can trigger errors ( don't recall if the out of memory error was one of them) when no-one is logged into the server, even if out MTS component that calls the CR8 Engine DLL is set to run under the local admin account. We solved this by re-installing MDAC after installing Net8 or any patches to it.

We received out of memory errors printing and exporting CR8 reports under MTS component control when the parameters were not perfectly matched and/or when the DSN was not exactly the same (name, vendor, version) as the one used to create the report (we develop the reports on a desktop and run them on a server). We also experienced it on some reports when the data was incomplete (a report design issue or a flaw in CR8). In this case, the error could be replicated when the report was triggered through the standard CR user interface.

The material I have read state that an MTS component must instantiate another MTS component with the CreateInstance method of the MTS context object. CreateObject should not be used in this context. From what I can tell, this is required for transactional integitry and facilitates connection pooling and memory cleanup (the .SetAbort method signals that the object and it's connection ca be released).

Multiple books on MTS progamming state that &quot;As NEW&quot; must be avoided, as should all forms of early binding. MTS components must be late bound because MTS substitutes it's class ID for the class IDs of the component and early binding circumvents this substitution. We use &quot;DIM X as whatever&quot; to get the editing features, but always instantiate objects with CreateObject and CreateInstance (for transactional MTS components).

Larry

Larry
Larryh@ecn.ab.ca

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top