Bartend.exe Memory Usage Grows, Then Ole Error 追蹤

0
Avatar
Legacy Poster

[code]BarTender Edition: Enterprise Automation
Version: 9.4 SR3
Build: 2781

Windows 7 - Build 7601 (Service Pack 1)
[/code]

We have an application (running as an Application, not a Service) that uses [b]Seagull.BarTender.Print.Engine[/b] to print .btw label files. The application works almost perfectly. It runs continuously for weeks at a time, printing thousands of labels.

Our application prints 2 kinds of labels, to 2 different printers. It creates 2 instances of the BarTender Engine (one for Label A/Printer A, and one for Label B/Printer B ).

Our BarTender usage is roughly:

[code]
LabelFormatDocument doc = myEngine.Documents.Open(path);
for each label // usually loops either once, or 10 times
{
for each SubString in doc.SubStrings
{
SubString.Value = some string value from our database;
}
doc.Print(jobName, out msgs);
}
doc.Close(SaveOptions.DoNotSaveChanges);
[/code]

When it prints "A" labels, it usually prints about 10 at at time.
When it prints "B" labels, it just prints one.

During production, the sequence is roughly like this:

[code]
every 3 minutes or so
{
print 10 "A" labels
print 1 "B" label
print 1 "B" label
print 1 "B" label
print 1 "B" label
}
[/code]

So the bartend.exe instance for our "A" labels calls [b]LabelFormatDocument.Print[/b] about 3x more often than the "B" instance. And the instance for our "B" labels calls [b]Engine.Documents.Open[/b] about 4x more often than the "A" instance.

Over time, you can see the amount of memory used by the bartend.exe processes grow (as shown by Windows Task Manager). The memory usage grows for both instances, but one instance grows to ten times that of the other instance. For example, after 3 weeks of continuous running, I can right now see the amount of memory used by one of the processes is over 660,000 K, and the other is about 60,000 K. Eventually our call to [b]Engine.Documents.Open(path)[/b] (for a "B" label) will throw this exception:

[code]
OLE received a packet with an invalid header. (Exception from HRESULT: 0x80010111)
[/code]

At that point, our application tries to recover from the situation by calling Stop() and Dispose() on both of our BarTender engine instances. Then, the next time a label is requested the application attempts to create a new Engine instance, but usually hits the following exception:

[code]The BarTender engine could not be started. Possible reasons are:

1) BarTender is not properly installed.
2) BarTender is not properly registered on the computer (e.g bartend.exe /register).
3) There are too many process instances of BarTender running. Stop a few bartend.exe instances and try again. Also see SDK Engine.Start method documentation for information about how to allow more BarTender processes to run on your computer by increasing your "non-interactive" shared desktop heap.
[/code]

At that point there are [b]no[/b] instances of bartend.exe running, so "possible reason #3" cannot be the problem. And I don't think the problem can be #1 or #2 either.

At this point, the only solution seems to be to stop and restart our application (and sometimes to reboot the machine too).

7 意見

0
Avatar
Michael Toupin (mtoupin
評論操作 永久連結

[quote name='jroe' timestamp='1350923375' post='3553']
[code]BarTender Edition: Enterprise Automation
Version: 9.4 SR3
Build: 2781

Windows 7 - Build 7601 (Service Pack 1)
[/code]

We have an application (running as an Application, not a Service) that uses [b]Seagull.BarTender.Print.Engine[/b] to print .btw label files. The application works almost perfectly. It runs continuously for weeks at a time, printing thousands of labels.

Our application prints 2 kinds of labels, to 2 different printers. It creates 2 instances of the BarTender Engine (one for Label A/Printer A, and one for Label B/Printer B ).

Our BarTender usage is roughly:

[code]
LabelFormatDocument doc = myEngine.Documents.Open(path);
for each label // usually loops either once, or 10 times
{
doc.Print(jobName, out msgs);
}
doc.Close(SaveOptions.DoNotSaveChanges);
[/code]

When it prints "A" labels, it usually prints about 10 at at time.
When it prints "B" labels, it just prints one.

During production, the sequence is roughly like this:

[code]
every 3 minutes or so
{
print 10 "A" labels
print 1 "B" label
print 1 "B" label
print 1 "B" label
print 1 "B" label
}
[/code]

So the bartend.exe instance for our "A" labels calls [b]LabelFormatDocument.Print[/b] about 3x more often than the "B" instance. And the instance for our "B" labels calls [b]Engine.Documents.Open[/b] about 4x more often than the "A" instance.

Over time, you can see the amount of memory used by the bartend.exe processes grow (as shown by Windows Task Manager). The memory usage grows for both instances, but one instance grows to ten times that of the other instance. For example, after 3 weeks of continuous running, I can right now see the amount of memory used by one of the processes is over 660,000 K, and the other is about 60,000 K. Eventually our call to [b]Engine.Documents.Open(path)[/b] (for a "B" label) will throw this exception:

[code]
OLE received a packet with an invalid header. (Exception from HRESULT: 0x80010111)
[/code]

At that point, our application tries to recover from the situation by calling Stop() and Dispose() on both of our BarTender engine instances. Then, the next time a label is requested the application attempts to create a new Engine instance, but usually hits the following exception:

[code]The BarTender engine could not be started. Possible reasons are:

1) BarTender is not properly installed.
2) BarTender is not properly registered on the computer (e.g bartend.exe /register).
3) There are too many process instances of BarTender running. Stop a few bartend.exe instances and try again. Also see SDK Engine.Start method documentation for information about how to allow more BarTender processes to run on your computer by increasing your "non-interactive" shared desktop heap.
[/code]

At that point there are [b]no[/b] instances of bartend.exe running, so "possible reason #3" cannot be the problem. And I don't think the problem can be #1 or #2 either.

At this point, the only solution seems to be to stop and restart our application (and sometimes to reboot the machine too).
[/quote]

You might want to consider looking at using the BarTender Print Server SDK to manage the BarTender processes. The Print Server SDK uses the TaskManager class, which manages a queue of tasks services by a pool of BarTender processes. So what would happen in this case is that you could have a queue of 3 or 4 Bartender processes that would share the print load between the processes. You can configure the task manager so that it will recycle the processes on a timer to eliminate issues like this.

Take a look at our help files discussing the Print Server SDK to see how this can be implemented in your scenario.
0
Avatar
Legacy Poster
評論操作 永久連結

[quote name='Mike T - Seagull Support' timestamp='1351033127' post='3568']
You might want to consider looking at using the BarTender Print Server SDK to manage the BarTender processes. The Print Server SDK uses the TaskManager class, which manages a queue of tasks services by a pool of BarTender processes. So what would happen in this case is that you could have a queue of 3 or 4 Bartender processes that would share the print load between the processes. You can configure the task manager so that it will recycle the processes on a timer to eliminate issues like this.

Take a look at our help files discussing the Print Server SDK to see how this can be implemented in your scenario.
[/quote]

Hmm... I don't want to re-architect my application at this point. Unless of course I'm actually doing something [b]wrong[/b] now. Am I?
0
Avatar
Legacy Poster
評論操作 永久連結

Should I Dispose my Engine instances periodically?

Should I be able to hang onto an Engine instance and use it for the entire lifetime of my application -- which ought to be several months?

Is the .NET SDK not designed to be used in this way?
0
Avatar
Legacy Poster
評論操作 永久連結

Hello?
Seagull?
Can someone answer my last set of questions?
0
Avatar
Legacy Poster
評論操作 永久連結

I now have statistics on the memory usage of the bartend.exe processes. Here is the usage for the process which eventually hit the OLE error.

[code]
10/26/2012 00:00:21 - docs: 131 - labels: 1139 - Mem4:[ 61]Mem5:[ 67]Mem6:[ 324]Mem7:[ 340]
10/27/2012 00:00:28 - docs: 325 - labels: 2623 - Mem4:[ 83]Mem5:[ 89]Mem6:[ 341]Mem7:[ 356]
10/28/2012 00:00:34 - docs: 510 - labels: 4159 - Mem4:[106]Mem5:[112]Mem6:[ 358]Mem7:[ 373]
10/29/2012 00:00:38 - docs: 742 - labels: 7266 - Mem4:[155]Mem5:[161]Mem6:[ 416]Mem7:[ 432]
10/30/2012 00:00:41 - docs: 961 - labels: 9781 - Mem4:[193]Mem5:[199]Mem6:[ 449]Mem7:[ 464]
10/31/2012 00:03:08 - docs:1210 - labels:12237 - Mem4:[231]Mem5:[237]Mem6:[ 482]Mem7:[ 499]
11/01/2012 00:00:34 - docs:1416 - labels:15019 - Mem4:[275]Mem5:[281]Mem6:[ 533]Mem7:[ 547]
11/02/2012 00:10:19 - docs:1482 - labels:15915 - Mem4:[288]Mem5:[294]Mem6:[ 548]Mem7:[ 565]
11/03/2012 00:05:49 - docs:1519 - labels:16185 - Mem4:[292]Mem5:[298]Mem6:[ 548]Mem7:[ 565]
11/04/2012 00:00:09 - docs:1696 - labels:17830 - Mem4:[317]Mem5:[323]Mem6:[ 583]Mem7:[ 597]
11/05/2012 00:00:10 - docs:1939 - labels:19580 - Mem4:[343]Mem5:[349]Mem6:[ 615]Mem7:[ 631]
11/06/2012 00:00:43 - docs:2160 - labels:21471 - Mem4:[372]Mem5:[378]Mem6:[ 649]Mem7:[ 663]
11/07/2012 00:00:48 - docs:2418 - labels:23921 - Mem4:[409]Mem5:[415]Mem6:[ 681]Mem7:[ 697]
11/08/2012 00:00:21 - docs:2616 - labels:26019 - Mem4:[441]Mem5:[447]Mem6:[ 718]Mem7:[ 728]
11/09/2012 00:02:14 - docs:2804 - labels:27600 - Mem4:[464]Mem5:[470]Mem6:[ 731]Mem7:[ 747]
11/10/2012 11:49:20 - docs:2923 - labels:28539 - Mem4:[478]Mem5:[484]Mem6:[ 747]Mem7:[ 763]
11/11/2012 00:01:56 - docs:3020 - labels:29508 - Mem4:[493]Mem5:[499]Mem6:[ 768]Mem7:[ 779]
11/12/2012 00:00:26 - docs:3238 - labels:31915 - Mem4:[530]Mem5:[536]Mem6:[ 800]Mem7:[ 813]
11/13/2012 00:00:23 - docs:3445 - labels:34221 - Mem4:[565]Mem5:[571]Mem6:[ 830]Mem7:[ 845]
11/14/2012 00:00:14 - docs:3636 - labels:36456 - Mem4:[600]Mem5:[605]Mem6:[ 863]Mem7:[ 880]
11/15/2012 00:00:06 - docs:3847 - labels:38693 - Mem4:[634]Mem5:[639]Mem6:[ 898]Mem7:[ 912]
11/16/2012 00:10:39 - docs:4015 - labels:39805 - Mem4:[650]Mem5:[656]Mem6:[ 913]Mem7:[ 927]
11/17/2012 00:00:04 - docs:4240 - labels:42654 - Mem4:[694]Mem5:[700]Mem6:[ 964]Mem7:[ 979]
11/17/2012 17:34:18 - docs:4409 - labels:44552 - Mem4:[723]Mem5:[729]Mem6:[1002]Mem7:[1013]

Legend
======
docs: the number of times Engine.Documents.Open(path) has been called
labels: the number of times LabelFormatDocument.Print has been called
Mem4: the result of Process.PagedMemorySize64 / 1000000
Mem5: the result of Process.PeakPagedMemorySize64 / 1000000
Mem6: the result of Process.VirtualMemorySize64 / 1000000
Mem7: the result of Process.PeakVirtualMemorySize64 / 1000000
[/code]
This bartend.exe process was started on Oct. 25 and ran perfectly until Nov. 17 at 5:34pm, at which point it hit the OLE error.

I have thoroughly documented my usage of the .net SDK in this thread.

Could someone from Seagull either confirm that you have a memory leak, and indicate when it will be fixed, or let me know how my usage of the .net SDK is incorrect and what I should be doing instead.
0
Avatar
Legacy Poster
評論操作 永久連結

In case anyone else is having similar problems, apparently the answers to these questions are...

[quote name='jroe' timestamp='1351533087' post='3600']
Should I Dispose my Engine instances periodically?
[/quote]
Yes! Or call Engine.Restart.

[quote name='jroe' timestamp='1351533087' post='3600']
Should I be able to hang onto an Engine instance and use it for the entire lifetime of my application -- which ought to be several months?
[/quote]
You should only do that if you periodically call "Restart" on the engine. (Every hour, ... maybe every day.)

[quote name='jroe' timestamp='1351533087' post='3600']
Is the .NET SDK not designed to be used in this way?
[/quote]
No, the engine should only be used continuously if you add the periodic calls to "Restart".
0
Avatar
Legacy Poster
評論操作 永久連結

Unfortunately, calling [b]Engine.Restart[/b] did not resolve the problem with the OLE error.

Calling [b]Engine.Restart[/b] does seem to effectively work around the bartend memory leak, but maybe the memory leak is unrelated to the OLE error.

登入寫評論。