Gary, yes I was suspicious about doing that... in the end, it didn't work. When we use the same FeatureClass instance for the whole process, at some point, the process hangs at the function "FeatureClass.Search". So no luck with this work-around...
Good luck with trying to open the featureclass once per run. Thats exactly what i'm doing and after a few runs my process crashes or gives me an "attempted to read or write protected memory" error that we traced down to the FeatureClass.Search() call. Seems to me even between runs the featureclass is being held and some sort of memory buildup causes our crash. If you have better luck please let me know. Jason, from this post, has tried to help us with our problem too which is greatly appreciated.Gary
I'm currently developing a work-around, I'll try to perform the OpenFeatureClass only once per feature class during the whole 2-3 days process. At this point, I need to prove that calling OpenFeatureClass many times is the culprit in our process crash. Joel
For 1 loop that opens the 21 feature classes, the memory increases of 40 Kb. But it's not constant, it varies between 38 Kb and 47 Kb. And it really keeps increasing steadily at every iteration. I did a simple test yesterday. To eliminate the COM wrappers from the equation, I did the same small application in Visual Basic 6. Turns out I had the same behavior, the memory won't free even if I set the FeatureClass variable to "Nothing". I'm currently developing a work-around, I'll try to perform the OpenFeatureClass only once per feature class during the whole 2-3 days process. At this point, I need to prove that calling OpenFeatureClass many times is the culprit in our process crash. I'll try to spend some time on the points 2) and 3) of your previous post. Thanks a lot, you provided very helpful advice. I'll give feedback about my work-around. Joel
How much is memory usage increasing between iterations? Does it keep increasing each time if you run the workflow multiple times?There are a number of possibilities. Here are a few off the top of my head:1) Some of the unmanaged memory could be the JIT-compiled code, which would only show up the first time you execute a method. Each method is compiled and the machine code cached in memory the first time a method is executed. The cached machine code stays in memory (unmanaged memory) until the process is torn down, if I remember correctly.2) Events may be fired when you open the feature class that cause other code to execute and allocate memory. If it is ArcFM, it will be harder to tell because I'm pretty sure they don't make their symbol files available. If you don't have symbol files, then you'll get something like this: mmGeoObjects!???+00000000 : 27412D03 that can show you the DLL, but not the class or method names. If there is a way to run your tests with ArcFM out of the picture, it should give you some idea as to whether ArcFM is contributing to your problem. If you know where to find ArcFM's symbol files or symbol server, please let me know--I could make use of them, too.3) UMDH doesn't just show leaks. It shows all the memory that was allocated between marks including things that ought not be released yet. You can limit the marks to only memory that is no longer referenced by using UMDH's -g flag when you mark memory. This may narrow your search some.You can also try the LeakDiag tool. I don't remember which heaps that UMDH monitors and doesn't monitor. There is a book called Advanced Windows Debugging that explains all of that. Unfortunately, I had to leave the copy I had with my previous employer since they bought it for me. I need to replace that because it is extremely useful in situations like this.
Jason, I agree, the OpenFeatureClass is not logged in the result. But, I would like be able to explain why the SciTech .NET Memory Profiler displays an increase of the "Unidentified unmanaged heaps" memory when this loop is performed. In the result.txt file, I see other call stack trace related to ESRI objects, some of them: Related to Miner & Miner ArcFM: mmGeoObjects!???+00000000 : 27412D03 mmSystemObjects!DllGetClassObject+0000D4FBOthers: Geometry!SpatialReferenceEnvironment::CreateESRISpatialReference+00000019 SdeFDB!SdeCursor::SetupGeometry+000000D9 sde!SES_stream_ok+00000B04 GdbCore!ClassHelper::Init+0000002BI think it is fair to say that, since the scope of the memory marking is only for the "OpenFeatureClass" function, these functions end up being called when doing "OpenFeatureClass". For some reasons, UMDH doesn't seem to be able to trace the function call stack back to "OpenFeatureClass" function... Thanks again for your help, Joel
Joel,The results you posted look pretty good actually. I don't see any leaks as a result of the OpenFeatureClass call. In fact, if you do a search on "OpenFeatureClass" in the document, it returns nothing, which is a good indicator that it isn't responsible for whatever UMDH caught. Did your test code show the same problem that your production code is showing? If not, then I think that the problem may be on your side. If the test code does show the same problem, but UMDH didn't turn anything up, you may need to look at other sections of code.You should also try what Kirk suggested. I think he doesn't expect any difference (nor do I), but it never hurts to try.I'll let you know if I have time to construct an example using my own data that will reproduce the problem. Please keep posting your progress on the board.Thanks,Jason
Jason,Could you expand a little on your statement
I would avoid using Esri's ComReleaser object--it is only useful in very specific situations and will cause problems in every other situation.
Thank you for your help, Jason. I followed the procedure with the Windows Debugging Tools. To give you an idea of my test, here is the loop that i executed right after I start marking the memory: For i As Integer = 1 To 5[INDENT]'There is about 21 feature classes in that "_featureClassNames" collection For Each featureClassName As String In _featureClassNames[INDENT]Dim esriFeatureClass As Geodatabase.IFeatureClass = NothingesriFeatureClass = _featureWorkspace.OpenFeatureClass(featureClassName)Marshal.ReleaseComObject(esriFeatureClass)[/INDENT]Next[/INDENT]NextThen took the second mark after and did the difference. I attached the result file to the thread (results.txt). I did a research with the "ESRI" keyword in the text file and i can find a couple of places where we can see the trace of the memory allocated. So do you think there is something wrong in my code? Or that the ESRI objects are not released and that I don't have any control on this? Thanks again, very appreciated! Joel
wsFactory = New DataSourcesGDB.SdeWorkspaceFactory()
Dim factoryType As Type = Type.GetTypeFromProgID("esriDataSourcesGDB.SdeWorkspaceFactory") Dim workspaceFactory As IWorkspaceFactory = CType(Activator.CreateInstance(factoryType), IWorkspaceFactory)
One thing that you might be able to do is to try to work around the problem by giving ArcMap more memory.You can do that by setting the large address aware bit on ArcMap.exe and then run your problem on a 64 bit operating system.Normally, ArcMap gets 2 GB and the OS gets 2 GB of virtual memory. If you do the above then the OS can move elsewhere leaving ArcMap with 4 GB of memory.
Hello ESRI developer community, I've been working with the ESRI ArcObjects for many years now, mainly on an ETL (Extract/Transform/Load) .NET application. This application can run for a long time to transfer data from an ESRI Geodatabase to the target system (for example, 3 consecutive days). We recently had a situation where our application crashes with an "OutOfMemory" exception. To find the memory leak, we profiled our application with SciTech .NET Memory Profiler. Since ArcObjects is a COM based library and that the application profiler can't give the detail about the instanciated objects, I had to comment the code of our application to narrow the possibilities of the objects used/function calls that was causing this memory leak. I ended up isolating the IFeatureWorkspace.OpenFeatureClass function being the main source of the problem. This function is called multiple times during the 2-3 days of process and it seems like the FeatureClass object returned is never released. I read multiple articles about memory leak with ArcObjects and tried everything that was suggested to release the FeatureClass object, i.e.:The .NET functions:Marshal.ReleaseComObjectMarshal.FinalReleaseComObjectThe ArcObject ComReleaser object with the following logic:Using comReleaser As New ComReleaser() esriFeatureClass = _featureWorkspace.OpenFeatureClass(featureClassName) comReleaser.ManageLifetime(esriFeatureClass)End UsingAll this combined with the .NET Garbage Collector functions:GC.CollectGC.WaitForPendingFinalizersI did a small application that simulates the same routine that our ETL application does to help for the profiling and also validate that the behavior is the same. It turns out it has the same behavior, the amount of memory allocated is similar. With the routine of opening the feature class repeated 450 times, there is 15 Mb that stays allocated at the end (SciTech Memory Profiler screenshot attached). So when the process runs for 3 days, there is more than 200 Mb that stays allocated just for those FeatureClass alone. I attached the Visual Studio 2010 project that does the routine, so if you want to take a look at the code to see if i'm missing something. Right now, I'm out of solution to fix that. Any help would be greatly appreciated. I'm working with ESRI ArcGIS 9.3 (9.3.0.1770 is the version number of the ESRI DLLs in Visual Studio)Thanks in advance, Joel
Imports ESRI.ArcGIS.ADF Imports ESRI.ArcGIS.DataSourcesFile Imports ESRI.ArcGIS.DataSourcesGDB Imports ESRI.ArcGIS.esriSystem Imports ESRI.ArcGIS.Geodatabase Imports ESRI.ArcGIS.Geometry Imports ESRI.ArcGIS Imports System.Runtime.InteropServices Public Class Form1 Private _featureClassNames As List(Of String) Private _featureWorkspace As IFeatureWorkspace Private Sub InitializeFeatureClassNames() _featureClassNames = New List(Of String) _featureClassNames.Add("ARCFM.Airport") _featureClassNames.Add("ARCFM.Bridge") _featureClassNames.Add("ARCFM.Building") _featureClassNames.Add("etc...") End Sub Private Sub ESRI_Connect() Dim propSet As New ESRI.ArcGIS.esriSystem.PropertySet Dim wsFactory As Geodatabase.IWorkspaceFactory = Nothing Try wsFactory = New DataSourcesGDB.SdeWorkspaceFactory() propSet = New ESRI.ArcGIS.esriSystem.PropertySet() With propSet .SetProperty("SERVER", "put SDE server name here") .SetProperty("INSTANCE", "put SDE service port here") .SetProperty("DATABASE", "put Oracle database service name here") .SetProperty("USER", "put Oracle user name here") .SetProperty("PASSWORD", "put Oracle user password here") .SetProperty("VERSION", "SDE.DEFAULT") End With 'Try to access the ESRI source data _featureWorkspace = wsFactory.Open(propSet, 0) Finally If propSet IsNot Nothing Then Marshal.ReleaseComObject(propSet) If wsFactory IsNot Nothing Then Marshal.ReleaseComObject(wsFactory) End Try End Sub ''' <summary> ''' This is the main loop where the Workspace.OpenFeatureClass function is called. ''' </summary> ''' <remarks></remarks> Private Sub LoopOpenFeatureClasses() For Each featureClassName As String In _featureClassNames Dim esriFeatureClass As Geodatabase.IFeatureClass = Nothing Try esriFeatureClass = _featureWorkspace.OpenFeatureClass(featureClassName) Catch ex As Exception Finally If esriFeatureClass IsNot Nothing Then Marshal.ReleaseComObject(esriFeatureClass) End Try Next End Sub ''' <summary> ''' Initializes the application to use the ArcObjects libraries. ''' </summary> ''' <remarks></remarks> Public Sub InitializeArcObjects() Dim aoInitialize = New AoInitialize() Dim licenseStatus As esriLicenseStatus = aoInitialize.Initialize(esriLicenseProductCode.esriLicenseProductCodeArcView) End Sub Private Sub btnTest_Click(sender As System.Object, e As System.EventArgs) Handles btnTest.Click Try InitializeFeatureClassNames() InitializeArcObjects() ' initializes _featureWorkspace ESRI_Connect() For i As Integer = 1 To 450 LoopOpenFeatureClasses() Next Catch ex As Exception Finally If _featureWorkspace IsNot Nothing Then Marshal.ReleaseComObject(_featureWorkspace) End Try End Sub End Class
cache*C:\dev\symbols;SRV*C:\dev\symbols*http://msdl.microsoft.com/download/symbols;SRV*C:\dev\symbols*http://downloads2.esri.com/Support/symbols/
Membros conectados podem postar, seguir atualizações e mais. Novo aqui? Registre uma conta gratuita.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.