Runtime Management and Diagnostics

Threading and Thread Safety

In general all classes in the toolkit are thread safe, with the exception of MCattributeSet class and its derived classes: MCdimseMessage, MCitem, MCfile and MCdicomDir.

The toolkit uses internal thread pools for managing association related activity. Each association is assigned its own thread for the lifetime of the association, after which the thread is reused for other associations or disposed if no other association is active. As a result, the methods of the MCassociation class are thread safe and can be called from any thread.

Memory Management and Performance

Several of the Merge DICOM Java classes are supported by objects maintained in the underlying Merge DICOM runtime C library. Each of the classes has a dispose method that you can call when you are finished with the class object to allow the resources in the runtime library to be released. Be careful, however, not to call dispose on an object that is still in use by another thread. Toolkit objects that are not explicitly disposes by the application will be disposed automatically by the toolkit when they are garbage collected.

To help diagnose resource problems, Merge DICOM Java Toolkit provides the MC.reportActiveMCObjects()method which sends diagnostic information to the toolkit's log.

The Merge DICOM runtime C library has its own native memory management routines that are optimized for how it uses memory. They have been adapted to manage specific data structures that are frequently allocated by Merge DICOM toolkit. These include but are not limited to data structures for associations, messages, and tags. The memory management routines have the characteristic that they do not actually free the memory that has been acquired. Instead, they mark the data as being free and place the memory in a list for reuse later. These routines have been optimized to quickly acquire and release memory being used by Merge DICOM toolkit. They also allow Merge DICOM toolkit to not depend on the memory management of a particular operating system.

The end result of these routines is that applications using Merge DICOM Java toolkit expand to the maximum amount of native memory used at one time. The total memory allocation will not shrink from this point. In applications that repeatedly perform a consistent operation, the memory being used by Merge DICOM toolkit should stabilize and not increase in size. As a result of these routines, the first time an application performs a DICOM operation is typically slower than subsequent operations. The application can request however a native memory cleanup using the MC.cleanupMemory() method. Information on the native memory usage of the toolkit can be obtained using the MC.reportNativeMemory() method.

There two main configuration items that can reduce the native memory usage of the toolkit: LARGE_DATA_STORE and LARGE_DATA_SIZE. These options control the ability of the toolkit to store pixel data in temporary files instead of RAM. This functionality is enabled by setting LARGE_DATA_STORE to FILE, and adjusting LARGE_DATA_SIZE to the size of data element that you want spooled to temporary file. Note however that this will decrease performance.

The WORK_BUFFER_SIZE option specifies how the toolkit buffers data before storing it or passing it to the application. Setting higher values for this option will increase performance.

The PDU_MAXIMUM_LENGTH option sets the maximum sized PDU that the toolkit will receive. If during association negotiation the maximum sized PDU of the system negotiating with the toolkit application is larger than this value, the PDU size will be limited to this value. Setting this option so that a PDU fits within an even multiple of the default TCP/IP Maximum Segment Size (MSS) of 1460 bytes will increase performance. Note that 6 bytes for the PDU header must be added to the configured maximum PDU size when calculating a multiple of the MSS. Having the PDU Maximum length an even multiple of the MSS ensures that there are limited delays within TCP/IP stack when transferring. With the exception of the final TCP/IP packet for a message, all packets transferred should exactly fit within a TCP/IP packet.

The TCPIP_RECEIVE_BUFFER_SIZE option sets the TCP/IP receive buffer size. Higher values for this buffer generally will increase the network performance of the toolkit for server (SCP) applications. This value should also be slightly larger than the PDU_MAXIMUM_LENGTH to increase performance. Setting this value to an even multiple of the MSS (1460 bytes) will help increase performance on most platforms.

The TCPIP_SEND_BUFFER_SIZE option sets the TCP/IP send buffer size. Higher values for this buffer generally will increase the network performance of the toolkit for client (SCU) applications. This value should also be slightly larger than the PDU_MAXIMUM_LENGTH to increase performance. Setting this value to an even multiple of the MSS (1460 bytes) will help increase performance on most platforms.

Exception Handling

The exceptions that each class may throw and the condition in which these exceptions are thrown are documented for each class.

Merge DICOM methods always throw exceptions of MCexception type which is a runtime exception derived from Java RuntimeException class.

In many cases, when an exception is thrown a message is logged to the Merge DICOM log file.

Each MCexception object has a public exceptionNumber field that identifies the exception category. The exception numbers are defined by static constants in the MCexception class.

Using the Merge DICOM Log

If you wish to log a message to the Merge DICOM log file (usually merge.log) you can use the MClog class. The same class can be used to configure the toolkit's logging feature at runtime.

You may want to capture log messages yourself, for example to integrate Merge DICOM log messages into your application's logging scheme. To do this, register an object that implements the MClogHandler interface using the MClog.addHandler() method. The toolkit will call the receiveLogMessage method of the registered handlers whenever it is logging a message. Information about the logged message is passed to the method in an instance of the MClogInfo class.