Redp 3950
Redp 3950
Rica Weller
Dave Clarke
Dave Griffiths
Introduction
This IBM Redpaper describes the following problem analysis tools for the IBM
WebSphere® for z/OS® production environment:
Svcdump.jar
HeapRoots
Dumpviewer GUI and jformat
This Redpaper goes into great detail about the switched virtual circuit (SVC)
Analyzer, explaining what svcdump.jar is, where to get it and when and how to
use its utilities. Finally, we list several samples for different parameter settings.
The HeapRoots utility and the DumpViewer GUI are mentioned for further
information.
These issues mean that we need to be able to acquire knowledge of the JVM
internals with less invasive diagnostic approaches, such as SDUMP, than are
typically used to diagnose problems in z/OS production environments.
The tools in this Redpaper provide you with the functionality to diagnose
problems that affect your important production workload, but are only
re-creatable in high transaction environments.
We see these approaches being driven initially by the systems programming staff
because they will have authority to access the SVC Dumps or Transaction
Dumps taken during failures. Systems programming staff also have the authority
Svcdump.jar
This section describes com.ibm.jvm.svcdump.Dump, com.ibm.jvm.findroots, and
the API. All are shipped in the svcdump.jar file. We cover installation and usage,
as well as arguments and properties that modify processing. We also deliver
sample output to enhance your understanding of the scope of these tools.
What is svcdump.jar?
Svcdump.jar enables access directly to the binary SVC Dump or Transaction
Dumps created on z/OS, without the need for intermediate software such as the
Interactive Problem Control System (IPCS).
Note: This paper is based on the 20041012 version of the code. Later
versions might offer additional function or different output.
If you experience an application loop or hang, then you can use the utility to
identify:
The thread under which a loop is occurring
The threads contending for resources or involved in a lockout
A thread waiting for an operation external to the server
In all of these cases, the reports can help you assign the failure to a particular
component or subcomponent before you report an incident to the IBM service
team. As an example, assume you have a couple of problems deploying an
updated version of an application:
A lockout seems to occur.
Inbound workload backs up and you console dump the servant address
space involved before recycling the J2EE server.
– Solution: Using the Dump utility, you find that the problem is a lockout
between two threads running framework code developed in-house.
Knowing this, you can circumvent IBM Service entirely. With the PMR
updates and documentation transmission that goes with it, turn the
problem directly over to your in-house development staff.
A crash occurs during a period of heavy load, and a Transaction Dump is
taken when the servant terminates.
– Solution: You discover that a crash has occurred in a JDBC native method.
You are able to direct the PMR you raise with IBM Service to the correct
IBM product support group in a timely manner, reducing your overall time
to resolve the problem.
To use the Dump utility, copy the three files in binary format to a suitable location
in the HFS. In our example, the files are in /u/dclarke.
Use the following command to confirm the version of the utility you are running:
Example 1 uses introspection to identify when this code was last modified.
Example 2 is a simple shell script that you can use to execute the utility:
/u/dclarke:==>svcdump.sh ONTOP.GS031.P10316.C724.JVMDMP
+ DUMPNAME=ONTOP.GS031.P10316.C724.JVMDMP
+ SVCDUMPJARFILE=/u/dclarke/svcdump20041007.jar
+ SVCDUMPLIBPATH=/u/dclarke
+ java -Xmx348m -Dsvcdump.libpath=/u/dclarke -
Xbootclasspath/p:/u/dclarke/svcdump20041007.jar -
Dsvcdump.default.jvm=0 com.ibm.jvm.svcdump.Dump -exception
ONTOP.GS031.P10316.C724.JVMDMP
+ 1>> ONTOP.GS031.P10316.C724.JVMDMP.svcdump.txt
Analysis of the dump can take some time, especially for the first execution. The
tool stores some heap information in a small .cache file, making subsequent
executions faster. Use this simple job control language (JCL) to run the utility in a
batch:
//STEP1 EXEC PGM=BPXBATCH,REGION=0M,
// PARM='SH /u/dclarke/svcdump.sh ONTOP.GS031.P10316.C724.JVMDMP’
The extract in Example 4 shows the report for one thread in one process, both
the native and Java stack for the same thread. It also shows the environment
variables and loaded dlls for each process for each address space found in the
dump. In this case, a thread is waiting on a socket for a reply from a Lightweight
Directory Access Protocol (LDAP) server.
Java stack:
Method Location
------ --------
java/lang/Object.wait Native Method
com/sun/jndi/ldap/Connection.readReply Connection.java:311
com/sun/jndi/ldap/LdapClient.ldapBind LdapClient.java:329
com/sun/jndi/ldap/LdapClient.authenticate LdapClient.java:160
com/sun/jndi/ldap/LdapCtx.connect LdapCtx.java:2405
com/sun/jndi/ldap/LdapCtx.<init> LdapCtx.java:258
com/sun/jndi/ldap/LdapCtxFactory.getInitialContext LdapCtxFactory.java:91
javax/naming/spi/NamingManager.getInitialContext NamingManager.java:674
javax/naming/InitialContext.getDefaultInitCtx InitialContext.java:255
<..>
com/ibm/ws390/wc/container/WebContainer.init WebContainer.java:61
com/ibm/ws390/WebContainerHook.init WebContainerHook.java:89
com/ibm/ws390/rmi/corba/ORBEJSBridge.initOnce ORBEJSBridge.java:1090
com/ibm/ws390/rmi/corba/ORBEJSBridge.threadInit ORBEJSBridge.java:1068
svcdump.default.asid none Mainly for use with jformat, this property specifies which address
space id (asid) to use as the default. The value must be given in hex
svcdump.default.jvm none In the case where there is more than one JVM present in an address
space, this property specifies the index of the default JVM to use.
svcdump.heapbase none This property specifies the heapbase to use when running with options
such as -verifyheap. This is useful when the heap corruption prevents
the heap walk from completing.
svcdump.numargs 4 This property specifies how many arguments to print when the -args
flag is used.
Svcdump.deref.args false This property prints what each argument points to (if possible)
-heap print a table showing which classes have the most objects
allocated
-dump <addr> <n> dump <n> words of storage starting at <addr> (hex)
-fullversion print the version of the jvm in the dump and exit
-time print time of the dump and exit-dis <addr> <n> disassemble
<n> instructions starting at <addr> (hex)
-heap
The -heap option prints a table showing which classes have the most objects
allocated.
Example 6 -heap
*** dump of live objects in the heap ***
count class
----- -----
71866 java/lang/String
70920 array of char
12164 java/util/HashMap$Entry
11008 java/lang/StringBuffer
6560 java/util/Hashtable$Entry
5474 java/util/zip/ZipEntry
<..>
In Example 6, the heap has 226518 objects occupying some 17.67 MB.
-alloc
The -alloc option prints the alloc cache. One of the optimizations in the storage
subcomponent of the JVM is the alloc cache or Thread Local Heap (TLH). This is
maintained on an individual thread basis and provides an area of storage in
which small objects can be allocated without the overhead involved in allocating
the object in the normal heap. It is sometimes useful to be able to see objects
recently allocated in the TLH by a thread. Example 7 shows an empty alloc
cache.
-exception
The -exception option prints an old exception object associated with a thread.
This can be useful because of the nature of Java’s try catch handling of
exceptions. This can mask an underlying exception, as in Example 9:
-dumpclasses
The -dumpclasses option prints all methods with their unique signatures and all
static fields within the class, as in Example 12. This can be useful if you suspect
there is a mismatch between an updated class library and native code following
service application. For example, –dumpclass addr can be used to print just one
class.
-dumpobject <addr>
The -dumpobject <addr> option prints information about the object at a particular
address:
0x2bba5fd0: java/lang/String link bits 20 is live true is marked false
This indicates the type of the object, and whether the alloc bit is set (is live
true) for this chunk of the heap, or whether this chunk of the heap has had the
mark bit set during garbage collection (is marked true).
-dumpmdata <addr>
The -dumpdate <addr> option prints information from the method block at this
particular address. The method block maintains information about a specific
method, such as:
Dump of mdata at 0x281c6f4c
Method: java/io/BufferedInputStream.read(.BII)I
-dumpproperties
The -dumpproperties option prints property values that were set with the –D
arguments that passed to the JVM. It can act as a useful check. For example,
you can check whether or not changes made in the WebSphere Administrative
Console have been applied to the correct server. See Example 13.
-dumpnative
The -dumpnative option prints all the native methods in a dump, as in
Example 14.
java/util/TimeZone.getSystemTimeZoneID
(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
java/io/ObjectInputStream.latestUserDefinedLoader ()Ljava/lang/ClassLoader;
java/io/ObjectInputStream.bytesToFloats ([BI[FII)V
<..>
-dumpverbosegc
For recent levels of JDK Service, the JVM maintains an in-storage version of the
data. This data is printed when you set the –verbose:gc switch. The
–dumpverbosegc option prints this buffer. In Example 15, one of its uses is to see
if garbage collection pause times are increasing.
mark, sweep, compact Time in milliseconds for these parts of the garbage
collection cycle to complete
-heapstats
The -heapstats option prints summary information about the Java heap, as in
Example 16.
CEEOPCW
pthread_cond_wait
condWait
sysMonitorWait
lkMonitorEnter
@@GETFN
mmipSelectInvokeJavaMethod
INVOKDMY
EXECJAVA
mmipExecuteJava
xeRunJniMethod
jni_CallStaticVoidMethodA
ORBEJSBridge::threadInit()
SR_ExecutionThread::RemoveAndProcessWork(ThreadCleanUp*,TCB*)
SR_ExecutionRoutine
(unknown)
<..>
-systrace
The -systrace option prints a version of the z/OS system trace, formatted by asid
and time. For Language Environment functions, it will resolve the program status
word (PSW) from the interrupt to a function. It is useful for identifying a thread
running garbage collection code during a garbage collection cycle. See
Example 18.
-hpitrace
The -hpitrace option accesses the HPI subcomponent of the JVM. This
subcomponent is the layer closest to the underlying operating system. It
maintains an in-storage buffer tracing recent calls. Printing this buffer can help
identify otherwise hard to spot problems resulting from failing operations such as
pthread_quiesce_and_get_np() that are used to freeze threads prior to a
garbage collection cycle. See Example 19.
-verifyheap
You can use the -verifyheap option to look for errors in the heap. You might use
this option following an unexpected crash in the interpreter (functions starting
mmi*) or a just-in-time (JIT) method. See Example 21.
-verifysubpools
Use the -verifysubpools option to enable looking for errors in the JVM structures
that manage the JVM use of native memory. It is unrelated to the z/OS VSM
component.
-printroots
The -printroots option prints the root objects. The FindRoots utility does a more
useful job of this type of analysis from the perspective of diagnosing object leaks.
See Example 23.
As an example, imagine some state data for a transaction is kept as an XML data
object. The design is such that the data is only relevant for the life of the
transaction. The object is eligible for garbage collection after the transaction has
ended. However, there is a bug in the code. This bug causes some other global
object to maintain a reference to the XML data object after the end of the
transaction. Although the object itself is small, it contains a reference to
non-trivial numbers of objects created by XML parsing.
Although the package is called FindRoots for historical reasons, it is now split
into a number of smaller tools that do the same thing. The split is mainly to
separate the extraction of the heap from the subsequent analysis.
Figure 1 on page 22 shows the general approach to use the FindRoots utility.
com.ibm.jvm.findroots.Convert
.phd file
com.ibm.jvm.findroots.PrintDomTree
com.ibm.jvm.findroots.Print
com.ibm.jvm.findroots.PrintRoots
com.ibm.jvm.findroots.PrintTree
etc.
Reports
Figure 1 FindRoots approach for analysis
The advantage of this approach is that you can discuss and pass the smaller
.phd files among your team, rather than large SVC or transaction dumps.
Also note that Finalizer is a reference subclass. When you do this, you will no
longer see long chains of Finalizer objects.
When run with the new format .phd files, all of the Print commands also obey:
-Dfindroots.include.references=false
It is more flexible to keep the references in the .phd file and only exclude them
when running the analysis.
Print
Print simply prints the contents of a .phd file. To use the Print tool, execute the
following:
java -classpath svcdump.jar com.ibm.jvm.findroots.Print <filename>
By combining this with traditional Unix filters such as sort and uniq, you can
calculate which class has the most objects, as in the following command:
cut -d ' ' -f 3 output | sort | uniq -c | sort -n -r
PrintRoots
PrintRoots does traditional FindRoots analysis on a .phd file. To use PrintRoots,
type the following:
java -classpath svcdump.jar com.ibm.jvm.findroots.PrintRoots <filename>
You can also specify the maximum depth with the -Dfindroots.depth property.
Maybe this should be called the width property, because it means the maximum
number of levels of indent.
Tip: The default is currently 1000. If you make it too big, you can get very
large output.
PrintTree
PrintTree prints the tree below a given object. This approach short-circuits the
usual find roots analysis, so you need to already know the id of the object in
which you are interested. It is useful for iterative approaches, for example, if you
discover that the depth was not big enough and you do not want to start all over
again. To use the PrintTree command, do the following:
java -classpath svcdump.jar com.ibm.jvm.findroots.PrintTree -root <id>
<filename>
If you specify -inverse, then the inverse of the tree is printed. It prints the tree
above the given object, starting with the parents, then their parents and so on.
PrintDomTree
PrintDomTree calculates and prints the dominator tree. The dominator tree
displays the parent as the next object up in the original tree that dominates all
paths to the child. It collapses the tree, only showing the important parts from the
perspective of memory leak analysis. That is because a dominator of a given
object is responsible for keeping alive the given object.
The use of this tool is now our recommended approach to memory leak analysis.
To use the PrintDomTree tool, execute the following command:
java -classpath svcdump.jar com.ibm.jvm.findroots.PrintDomTree
<filename>
Notice that the dominator tree on the right does not necessarily reflect the direct
relationships between objects. For example, node 7 is a child of node 4 in the
dominator tree, but is a grandchild in the original tree on the left.
The number to the left on each line is the reachability for that object. It defines
either the number of objects or the size of memory occupied, depending on
whether you set the findroots.sizematters property. The reachability is defined as
the number of objects, or size occupied by them, reachable from a given object
by following reference links. This number is the total of the children, the children's
children and so on.
The second field is the address of the object in the heap. The third field is the
class name.
PrintClassReach
The PrintClassReach tool prints the space reachable by all objects of the given
class. To use the PrintClassReach to, execute the following command:
java -classpath svcdump.jar com.ibm.jvm.findroots.PrintClassReach
-class <classname> <filename>
Use this tool when you suspect that many objects of a given class are causing
the problem, rather than one particular object tree. Note that classname should
be written in directory style, that is java/lang/Object.
PrintComponents
PrintComponents does basically the same thing as PrintRoots, except that it
collapses the strong components into just one entry, producing a much less
cluttered output. The contents of the strong components are the numbers at the
end of the line. See Example 25.
Table 5 lists all the FindRoots utility properties and their default values.
findroots.depth 1000 This property controls how deep to print levels of indentation
in the output tree.
findroots.prune 1000 or Objects with reachability smaller than this amount are not
10 000 printed. This is to avoid cluttering the output with millions of
lines for objects that do not contribute much to the whole. The
default depends on whether sizematters is used, with the
larger value being sizematters=true. For the PrintTree
command, the default is zero.
findroots.sizematters false This property controls whether to base the reachability on the
cumulative size of each object, or the total number of
individual objects. In the vast majority of cases, size does not
matter. The real issue is the number of objects being kept
alive. Switching on sizematters will tell you how much actual
space is involved, but it does not change the basic structure
of the tree.
findroots.maxroots 20 This property controls how many roots are displayed, where
appropriate.
findroots.exact false This property controls whether to base the reachability on the
cumulative size of each strong component, rather than the
much quicker way of treating each component as one
element. As with sizematters, turning this on produces much
longer running times for the same reason, and in most cases
is not necessary. Switched it off effectively treats each strong
component as one node.
findroots.include.references true When used by Convert, this property controls whether or not
to include subclasses of java/lang/ref/Reference in the .phd
file. When used by the various Print* tools and set to false,
it can also be used to exclude instances of such subclasses.
findroots.calculate.reachability true For certain commands (for example, PrintTree) this property
determines whether or not to calculate the reachability. It
takes a lot more memory and time to calculate the
reachability. If you want to see the subtree for a particular
object only, turn it off.
Tip: TreeViewer is a simple GUI for displaying FindRoots output files. Give it
the name of the output file. TreeViewer displays just the top root in a pop-up
window. Click the expand tree icon to open the next level down and so on. It
is much easier to browse big trees like this.
We used Convert to create the .phd file. The original dump was enormous, 3 GB.
However, the resulting .phd file was only 43 MB, which was a lot easier to pass
among the team. There are a total of 4.4 million objects in this dump in a heap
size of 512 MB.
Notice the huge difference between the figure of 2547915 objects for the array
and only 266 for the WebAppInvoker. We set -Dfindroots.prune=0 to make the
children print.
Because children are printed in order of reachability with the biggest first, this
implies that the array must have many children. It is most likely that all the
children are going to be the same class.
- a grep for WebAppInvoker in the output piped into wc showed that there were
14700 instances of WebAppInvoker, all belonging to the array in CachedTargets.
We found logic that generated a unique URI for every request within the
application. This, in turn, skipped the cache and created a new WebAppInvoker
object each time. The number of unique URIs for the application appeared to be
infinite. Normally an application has, at most, 100 unique URIs.
http://www.alphaworks.ibm.com/tech/heaproots
HeapRoots version 2.0.4. Copyright (c) IBM Corporation 1996,2003. All rights reserved.
Type help for information about the supported commands, and then help o,
help g, and so on, for detailed help about these options. Table 6 shows the
supported options:
p/process/k/keep Processes the dump to find roots and other statistics. This
involves searching from each root in the graph.
Use p 0xaddr to start processing from 0xaddr so that it
gets bias when owning objects.
Use k 0xaddr to process the keep-alive size of 0xaddr.
This starts the same as p 0xaddr but then objects
reachable by other roots are removed from 0xaddr.
In Example 29 on page 33, we used dt to look at the object graph below the
com/ibm/servlet/engine/srt/CachedTargets object at 0x1b3da840. This shows
that the array is of com/ibm/servlet/engine/srt/WebAppInvoker objects.
in Example 30, we used the os command to locate the 25 largest items on the
heap.
The tools are shipped with the IBM JDKs on all platforms. The GUI is described
in some detail in the PD Guides shipped with the IBM JDKs at 1.3.1 and 1.4.1.
When the GUI initializes, use the File menu to locate the dump for initialization.
Restriction: For use on z/OS, you need to export the DISPLAY environment
variable to a valid X Server display on a Microsoft® Windows® 32 or Linux®
system.
With the Win32 JDK shipped with WebSphere on Microsoft Windows, the
formatter can be invoked with the jformat command:
C:\Program Files\IBM\Java142\bin\jformat
For more information, refer to the IBM diagnosis guides for the IBM JDKs:
For WebSphere V5.0
IBM® Developer Kit and Runtime Environment, Java™ 2 Technology Edition,
Version 1.3.1 Diagnosis Guide, SC34-6200
For WebSphere V5.1
IBM® Developer Kit and Runtime Environment, Java™ 2 Technology Edition,
Version 1.4.1 Diagnosis Guide, SC34-6309
You can download these manuals and detailed documentation for the Garbage
Collector used in the IBM JVM from:
http://www-106.ibm.com/developerworks/java/jdk/diagnosis/
The Svcdump.jar enables direct access to the binary SVC Dump or Transaction
Dumps created on z/OS, without the need for intermediate software such as
IPCS. The svcdump.jar is shipped to include:
Dump utility
The Dump utility ( com.ibm.jvm.svcdump.Dump package) formats native and
Java stacks for threads in dumped processes that include an instantiated
JVM. The Dump utility includes function to print out other useful information
such as in core trace buffers maintained by the JVM and the system trace,
mimicing or extending the information that can be obtained with IPCS.
FindRoots utility
FindRoots ( com.ibm.jvm.findroots.* package) provides multiple ways of
formatting the object graphs present in the Java-managed heap. This is
critical for the sometimes difficult tasks of finding object leaks and determining
heap occupancy.
The HeapRoots utility is shipped in HR204.jar and derives from the same
requirement to be able to map the heap object graphs. HeapRoots was originally
developed for the JVM shipped with AIX. It is now possible to seamlessly use this
code with binary SVC or Transaction Dumps, providing a range of additional
function to the FindRoots utility in svcdump.jar.
The Dumpviewer GUI and jformat are cross-platform utilities for reviewing native
and Java stacks. as well as providing facilities to help diagnose locking and
heap-related problems. On z/OS, the tools work directly with SVC or Transaction
dump, using the code from svcdump.jar.
Although we emphasize using the tools on z/OS, you are free to do the diagnosis
on the platform that suits you best because the tools are Java-based.
Clarke Dave is a Senior IT Specialist working for IBM Global Services, providing
technical support for WebSphere for z/OS customers in EMEA. He has 19 years
of experience in the IT industry working on z/OS and its precursors. In the past,
he worked as an MVS systems programmer, a software engineer in the IBM
Hursley lab service team for Java on z/OS and in a similar technical support role
for the z/OS MVS BCP. This included a stint in the Poughkeepsie lab in the MVS
supervisor level 2 team. He holds a Bachelor of Science in Chemistry from
Durham University in the United Kingdom.
Tamas Vilaghy
ITSO, Poughkeepsie Center
This information was developed for products and services offered in the U.S.A.
IBM may not offer the products, services, or features discussed in this document in other countries. Consult
your local IBM representative for information on the products and services currently available in your area.
Any reference to an IBM product, program, or service is not intended to state or imply that only that IBM
product, program, or service may be used. Any functionally equivalent product, program, or service that
does not infringe any IBM intellectual property right may be used instead. However, it is the user's
responsibility to evaluate and verify the operation of any non-IBM product, program, or service.
IBM may have patents or pending patent applications covering subject matter described in this document.
The furnishing of this document does not give you any license to these patents. You can send license
inquiries, in writing, to:
IBM Director of Licensing, IBM Corporation, North Castle Drive Armonk, NY 10504-1785 U.S.A.
The following paragraph does not apply to the United Kingdom or any other country where such
provisions are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION
PROVIDES THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR
IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer
of express or implied warranties in certain transactions, therefore, this statement may not apply to you.
This information could include technical inaccuracies or typographical errors. Changes are periodically made
to the information herein; these changes will be incorporated in new editions of the publication. IBM may
make improvements and/or changes in the product(s) and/or the program(s) described in this publication at
any time without notice.
Any references in this information to non-IBM Web sites are provided for convenience only and do not in any
manner serve as an endorsement of those Web sites. The materials at those Web sites are not part of the
materials for this IBM product and use of those Web sites is at your own risk.
IBM may use or distribute any of the information you supply in any way it believes appropriate without
incurring any obligation to you.
Information concerning non-IBM products was obtained from the suppliers of those products, their published
announcements or other publicly available sources. IBM has not tested those products and cannot confirm
the accuracy of performance, compatibility or any other claims related to non-IBM products. Questions on
the capabilities of non-IBM products should be addressed to the suppliers of those products.
This information contains examples of data and reports used in daily business operations. To illustrate them
as completely as possible, the examples include the names of individuals, companies, brands, and products.
All of these names are fictitious and any similarity to the names and addresses used by an actual business
enterprise is entirely coincidental.
COPYRIGHT LICENSE:
This information contains sample application programs in source language, which illustrates programming
techniques on various operating platforms. You may copy, modify, and distribute these sample programs in
any form without payment to IBM, for the purposes of developing, using, marketing or distributing application
programs conforming to the application programming interface for the operating platform for which the
sample programs are written. These examples have not been thoroughly tested under all conditions. IBM,
therefore, cannot guarantee or imply reliability, serviceability, or function of these programs. You may copy,
modify, and distribute these sample programs in any form without payment to IBM for the purposes of
developing, using, marketing, or distributing application programs conforming to IBM's application
programming interfaces.
Trademarks
The following terms are trademarks of the International Business Machines Corporation in the United States,
other countries, or both:
Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun
Microsystems, Inc. in the United States, other countries, or both.
Microsoft, Windows, and the Windows logo are trademarks of Microsoft Corporation in the United States,
other countries, or both.
UNIX is a registered trademark of The Open Group in the United States and other countries.
Linux is a trademark of Linus Torvalds in the United States, other countries, or both.
Other company, product, and service names may be trademarks or service marks of others.