JProfile Beginning

JProfile Beginning
 

JProfile Beginning

 

JProfiler 是一个著名的用于 java 系统监控分析的软件,功能很强大,可以监控普通的 java application, applet, java web start, application server 等等。除了可以监控本地的程序,还可以对远程服务器上跑的应用进行监控。

 

http://resources.ej-technologies.com/jprofiler/help/doc/indexRedirect.html?http&&&resources.ej-technologies.com/jprofiler/help/doc/ide/eclipse3.html

 

一、        JProfiler as an Eclipse 3.x Plugin

  When JProfiler is integrated into the eclipse 3.x IDE, JProfiler can be invoked from within the IDE without any further need for session configuration.

Requirements: The eclipse 3.x plugins work with the full SDKs for eclipse 3.0 and eclipse 3.1. The JProfiler integration does not work with partial installations of the eclipse framework. For eclipse 2.x, a different plugin is available.

 

  The installation of the eclipse plugin is started by selecting "eclipse 3.0" or "eclipse 3.1" on the

  • IDE integration tab of JProfiler's setup wizard
  • miscellaneous options tab of JProfiler's general settings (use Session->IDE integrations in JProfiler's main menu as a shortcut).

and clicking on [Integrate]

Reminder: Please close eclipse while performing the plugin installation. If you are performing the installation from JProfiler's setup wizard, please complete the entire setup first before starting eclipse.

A file selector will then prompt you to locate the installation directory of eclipse.

After acknowledging the completion message, you can start eclipse and check whether the installation was successful. If the menu item Run->Profile ... does not exist in the Java perspective, please enable the "Profile" actions for this perspective under Window->Customize perspective by bringing the Command tab to front and selecting the "Profile" checkbox.

eclipse provides shared infrastructure for profiling plugins that allows only one active profiler at a time. If another profiler has registered itself in eclipse, JProfiler will show a collision message dialog at startup. Please go to the plugin directory in your eclipse installation and delete the plugins that are specified in the warning message in order to guarantee that JProfiler will be used when you click on one of the profiling actions.

If you are upgrading the integration from JProfiler <=3.2, please delete your Eclipse "configuration" directory except the config.ini file before restarting Eclipse. This is to avoid a common Eclipse 3.x plugin cache bug.

 

  To profile your application from eclipse, choose one of the profiling commands in the Run menu or click on the corresponding toolbar button. The profile commands are equivalent to the debug and run commands in eclipse and are part of eclipse's infrastructure.


Main eclipse toolbar with "Profile" button
 


eclipse "Run" menu with "Profile" actions
 

The profiled application is then started just as with the usual "Run" commands. If no instance of JProfiler is currently running, JProfiler is also started, otherwise the running instance of JProfiler will be used for presenting profiling data.

Every time a run configuration is profiled, a dialog box is brought up that asks you whether a new window should be opened in JProfiler. To get rid of this dialog, you can select the "Don't ask me again" checkbox. The window policy can subsequently be configured in the JProfiler settings in eclipse (see below).

All profiling settings and view settings changes are persistent across session restarts.

When JProfiler is used with the eclipse integration, the "Show source" action for a class or a method in one of JProfiler's view will show the source element in eclipse and not in JProfiler's integrated source code viewer.

 

  Several JProfiler-related settings can be adjusted in eclipse under Window->Preferences->JProfiler:

  • The used JProfiler installation can be changed by repeating the integration from JProfiler or by adjusting the JProfiler executable in the corresponding text field. When you upgrade to a newer version of JProfiler, make sure to repeat the integration, since the plugin has to be updated, too.
  • The window policy can be configured as
    • Ask each time
      Every time you profile a run configuration, a dialog box will ask you whether a new window should be opened in JProfiler. This is the default setting.
    • Always new window
      Every time you profile a run configuration, a new window will be opened in JProfiler.
    • Reuse last window
      Every time you profile a run configuration, the last window will be reused in JProfiler.
  • You can manually repeat the collision detection that is performed at startup. With the corresponding checkbox, you can also switch off collision detection at startup.

·         You can ask JProfiler to always use interpreted mode for profiling. A separate checkbox tells JProfiler to use the deprecated JVMPI interface when profiling with a 1.5 JRE. Both these settings are trouble-shooting options and should normally not be selected.

 

  For eclipse 3.2 and higher, profiling WTP run configurations is supported.

二、        Overview of Features

  JProfiler's features are ordered into view sections. A view section can be made visible by selecting in JProfiler's sidebar. JProfiler offers the following view sections:

  • Memory profiling
    Keep track of your objects and find out where the problem spots are.
  • The heap walker
    Use the drill down capabilities of JProfiler's unique heap walker to find memory leaks.
  • CPU profiling
    Find out where your CPU time is going and zero in on performance bottlenecks.
  • Thread profiling
    Check the activity of your threads, resolve deadlocks and get detailed information on your application's monitor usage.

·         VM telemetry information
Unfold the statistical history of your application with JProfiler's virtual machine telemetry monitors.

 

  In order to help you find JProfiler's features which are most important to you, we present a situational overview. There are two types of uses for a profiler which arise from different motivations:

  • Problem solving
    If you turn to a profiler with a problem in your application, it most likely falls into one of the following three categories:
    • Performance problem
      To find performance related problem spots in your application, turn to JProfiler's CPU section. Often, performance problems are caused by excessive creation of temporary objects. For that case, the recorded objects views with its view mode set to "garbage collected objects" will show you where efforts to reduce allocations make sense.
    • Excessive memory consumption
      If your application consumes too much memory, the memory views will show you where the memory consumption comes from. With the reference views in the heap walker you can find out which objects are unnecessarily kept alive in the heap.
    • Memory leak
      If your application's memory consumption goes up linearly with time, you likely have a memory leak which is show stopper especially for application servers. The "mark current values and show differences" feature in the memory section and the heap walker will help you to find the cause.
    • Deadlock
      If you experience a deadlock, JProfiler's deadlock detection graph will help you to find the cause even for complex locking situations.
    • Hard to find bug
      A often overlooked but highly profitable use of a profiler is that of debugging. Many kinds of bugs are exceptionally hard to find by hand or by using a traditional debugger. Some bugs revolve around complex call stack scenarios (have a look at the CPU section), others around entangled object reference graphs (have a look at the heap walker section), both of which are not easy to keep track of.
      Particularly JProfiler's thread views are of great help in multi-threaded situations, where race-conditions and deadlocks are hard to track down.

·         Quality assurance
During a development process, it's a good idea to regularly run a profiler on your application to assess potential problem spots. Even though an application may prove to be "good enough" in test cases, an awareness for performance and memory bottlenecks enables you adapt your design decisions as the project evolves. In this way you avoid costly re-engineering when real-world needs are not met. Use the information presented in JProfiler's telemetry section to keep an eye on the evolution of your application. The ability to save profiling snapshots enables you to keep track of your project's evolution. The offline profiling capability allows you to perform automated profiling runs on your application.

 

三、        Finding a Memory Leak

1. Introduction

Unlike C/C++, Java has a garbage collector that eventually frees all unreferenced instances. This means that there are no classic memory leaks in Java where you forget to delete an object or a memory region. However, in Java you can forget something else: to remove all references to an instance so that the object can be garbage collected. If an object is only ever held in a single location, this may seem simple, but in many complex systems objects are passed around through many layers, each of which can add a permanent reference to the object.

Sometimes it appears to be clear that an object should be garbage collected when looking at the local environment of where the object is created and discarded. However, any call to a different part of a system that passes the object as a parameter can cause the object to "escape" if the receiver intentionally or by mistake continues to hold a reference to the object after the call has completed. Often, over-eager caching with the intention to improve performance or design mistakes where parallel access structures are built are the reason for memory leaks.

2. Recognizing a memory leak

The first step when suspecting a memory leak is to look at the heap and object telemetry views. When you have a memory leak in your application, these graphs must show a linear positive trend with possible oscillations on top.

If there's no such linear trend, your application probably simply consumes a lot of memory. This is not a memory leak and the strategy for that case is straightforward: Find out which classes or arrays use a lot of memory and try to reduce their size or number or instances.

3. Using differencing to narrow down a memory leak

The first stop when looking for the origin of a memory leak is the differencing action of the all objects view and the recorded objects view. Simple memory leaks can sometimes be tracked down with the differencing function alone.

First, you observe the differences in the all objects view or the recorded objects view and find out which class is causing the problems. Then you switch to the allocation hotspots view, select the problematic class and observe in the difference column in which method the problematic instances are allocated. Now you know the method in which these instances were created.

An analysis of the code for this method and the methods to which these instances are passed may already yield the solution to the memory leak. If not, you have to continue with the heap walker.

Another tool to observe instance counts that also presents a history of values is the class tracker. The class tracker shows graphs of instance counts versus time for selected classes and packages. When the difference columns in the "all objects" or "recorded objects" views identify suspicious classes, the class tracker can often generate further insight into the evolution of these instance counts since you can correlate jumps or increases in the allocation rate with other telemetry views or bookmarks.

4. The heap walker and memory leaks

When you take a heap snapshot, you first have to create an object set with those object instances or arrays that should be freed by the garbage collector but are still referenced somewhere. If you've already narrowed down the origin of the memory leak in the dynamic memory views, you can use the "Take heap snapshot for selection" action to save you some work and to start in the heap walker right at the point where you left off in the dynamic memory views.

By default, the heap walker cleans a heap snapshot from objects that are unreferenced but are still not collected by the garbage collector. This behavior can be controlled by the "Remove unreferenced and weakly referenced objects" option in the heap walker options dialog. When searching for a memory leak, this "full garbage collection" is desirable, since unreferenced objects are a temporary phenomenon without any connection to a memory leak.

If necessary, you can now further narrow down the memory leak by adding additional selection steps. For example, you can go to the data view and look at the instance data to find out a number of instances that definitely should have been freed. By flagging these instances and creating a new set of objects you can reduce the number of objects that are in your focus.

5. Using the reference graph to find the reason for a memory leak

The core instrument for finding memory leaks is the reference graph in the heap walker. Here you can find out how single objects are referenced and why they're not garbage collected. By successively opening incoming references you may spot a "wrong" reference immediately. In complex systems this is often not possible. In that case you have to find one or multiple "garbage collector roots". Garbage collector roots are points in the JVM that are not subject to garbage collection. These roots emanate strong references, any object that is linked by a chain of references to such a root cannot be garbage collected.

When you right-click on an object in the reference view, the context menu offers the option to search for paths to the garbage collector roots:

 

Potentially there are very many garbage collector roots and displaying them all can lead to the situation that a sizable fraction of the entire heap has to be shown in the reference graph. Also, looking for garbage collector roots is computationally quite expensive, and if thousands of roots can be found, the computation can take very long and use a lot of memory. In order to prevent this, it is recommend to start with a single garbage collector root and search for more roots if required. An option dialog is displayed after you trigger the search:

 

As you can see in this example, the chain to a garbage collector root can be quite long:

 

The reason for a memory leak can be anywhere along this chain. It is of a semantic nature and cannot be found out by JProfiler, but only by the programmer. Once you have found the faulty reference, you can work on your code to remove it. Unless there are other references, the memory leak will be gone.

6. Using the cumulated references views to find the reason for a memory leak

In some cases, you might not succeed in narrowing down the object set to a reasonable size. You object set might still contain a large number of instances that are OK and using the reference graph might not provide any insight in this situation.

If such a situation arises, the cumulated reference tables available in the reference view of the heap walker can be of help. The cumulated incoming reference table shows all possible reference types into the current object set:

 

From the reference type, you may be able to narrow down the object set. For example, you may know that one type of reference is OK, but another is not. As a hypothetical example, the reference from HashMap$Entry in the table above might be OK, but the reference from java.util.jar.Manifest might be suspicious. By selecting the 8 objects who are referenced in this way, you can discard the other 224 instances and use the reference graph to show the path to a garbage collector root.

 

 

 

 

四、        JProfiler's Menu

 

 

JProfiler's toolbar and menu contain actions applicable to all views as well as actions which are view-sensitive or appear for certain views only. The common menu and toolbar entries fall into six categories:

  The session menu contains actions to create, open and close sessions and snapshots.

  • Start center
    (
    CTRL-O) Brings up JProfiler's start center. If there already is an open session in the current window, it will be discarded once a new session is opened. This action is also available from JProfiler's toolbar.
  • New window
    (
    CTRL-ALT-O) Open in a new instance of JProfiler's main window and brings up JProfiler's start center.
  • New session
    (
    CTRL-N) Creates a new session and brings up the application settings dialog. The new session will be started after leaving the dialog with [OK]. If there is already an open session in the current window, it will be discarded.
  • Integration wizards
    This submenu contains the starting points for the application server integration wizards, just like the "New session" tab on the start center.
  • Conversion wizards
    This submenu contains the starting points for the conversion wizards, just like the "Convert" tab on the start center.
  • Open session
    Brings up the open session dialog. If there already is an open session in the current window, it will be discarded once a new session is opened.
  • Save snapshot
    (
    CTRL-S) Brings up a file chooser to select a snapshot file to be written. A dialog box informs about the successful completion of the operation. This action is also available from JProfiler's toolbar.
  • Open snapshot
    Brings up a file chooser to select a snapshot file to be opened. If there already is an open session in the current window, it will be discarded.
  • Session settings
    Brings up the session settings dialog. Note that any changes here become effective only when the session is restarted.
  • General settings
    Brings up the general settings dialog.
  • IDE integrations
    Short cut to the IDE integrations tab of the general settings dialog where you can integrate all supported IDEs.
  • Close window
    (
    CTRL-W) Closes the current window. If there is an open session in the current window, you will be asked for confirmation.

·         Exit JProfiler
(
CTRL-ALT-X) After confirmation, closes all open main windows and exits JProfiler.

 

  The view menu contains view-specific actions and gives access to the view settings dialog. View specific actions are described in the help page of the corresponding view.

·         View settings
(
CTRL-T) Brings up the view settings dialog for the corresponding view. If disabled, the currently active view has no particular settings. This action is also available from JProfiler's toolbar.

 

  The profiling menu contains actions which change the window or session as a whole.

  • Stop/Detach/Start/Attach session
    (
    F11) This action is also available from JProfiler's toolbar.
    •  Stops the session (all session types except remote session), i.e. the process is destroyed. In a stopped session, the profiling views are not fully functional (visible if currently started and not remote session).
    •  Detaches the current remote session. The profiled JVM will be detached from JProfiler's front end and continues to run undisturbed. In a detached session, the profiling views are not fully functional (visible if currently attached and remote session).
    • Starts the application configured in the current session if it is a local session, applet session or Web Start session (visible if currently detached and not remote session).
    • Attaches the current remote session to a remote application or reconnects to it. (visible if currently detached and remote session).
  • Freeze/Unfreeze session
    (
    F12) This action is also available from JProfiler's toolbar.
    • Freeze all views for the current session (visible if currently not frozen).
    • Unfreeze all views for the current session (visible if currently frozen).
  • Get current data
    (
    F5) Update all views with the current data. If the current session is frozen, this action reloads all views and is also available from JProfiler's toolbar. If the session is not frozen, only the current view is updated. This action only has an effect on dynamic views that get auto-updated, views where data is calculated on demand are not re-calculated with this action.
  • Record allocation data
    This action is also available from JProfiler's toolbar. The memory views and some telemetry views rely on allocation data.
    • Start recording allocation data. (visible if allocations are currently not recorded). Adds a bookmark with a solid line to all graph views with a time axis.
    • Stop recording allocation data. (visible if allocations are currently recorded). Adds a bookmark with a dashed line to all graph views with a time axis.
  • Record CPU data
    This action is also available from JProfiler's toolbar. The CPU views rely on CPU data.
    • Start recording CPU data. (visible if CPU data is currently not recorded). Adds a bookmark with a solid line to all graph views with a time axis.
    • Stop recording CPU data. (visible if CPU data is currently recorded). Adds a bookmark with a dashed line to all graph views with a time axis.
  • Save HPROF snapshot
    Brings up a dialog to select a path for an HPROF snapshot file to be saved. A dialog box informs about the successful completion of the operation.
  • Run garbage collector
    Run the garbage collector in the profiled JVM. This action is also available from JProfiler's toolbar.
  • Add bookmark
    Add a bookmark in all graph views with a time axis. Bookmarks can be renamed or deleted by right-clicking them and choosing the appropriate action from the context menu. Bookmarks can also be set programmatically from the profiling API.

·         Show global filters for method call recording
Show a dialog with a tree view of all exclusive or inclusive filters that JProfiler uses when recording the method call tree. This action is also available at the bottom of several views that show call trees.

 

  The go to menu provides one-click access to all of JProfiler's profiling views, grouped into the four         view sections.

 

  The window menu allows you to keep track of all tops level windows created by JProfiler.

  • Undock/Dock view
    (
    CTRL-E) This action is also available from the context menu when right clicking the view in the tab selector at the bottom of the window.
    •  Undocks the view and shows it in a separate top level window. (visible if the currently active view is docked into the main window)
    •  Docks the view and returns it to the main window. (visible if the currently active view is undocked)
  • Dock all floating views
    Docks all currently undocked views into their main windows.
  • Cycle to previous window
    (
    CTRL-F2) Activate the previous window in the window list and bring it to the front.
  • Cycle to next window
    (
    CTRL-F3) Activate the next window in the window list and bring it to the front.
  • Tile all undocked views
    Tile the desktop with all undocked views.
  • Stack all undocked views
    Resize all undocked views to a standard size and stack them regularly on the desktop.
  • Close unused console windows
    Close all console windows that do not have an active process associated with them.

At the bottom of the window menu you can directly navigate to a window by selecting it from the list.

 

  The help menu gives access to help, web sites, and useful e-mail addresses for JProfiler.

  • Help contents
    (
    F1) Brings up context sensitive help. This action is also available from JProfiler's toolbar.
  • JProfiler on the web
    Connects to JProfiler's web site in the web browser configured under general settings.
  • Contact sales
    Brings up a sales contact form in the web browser configured under general settings.
  • Contact support
    Brings up a support contact form in the web browser configured under general settings.
  • Enter license key
    Allows you to enter your license key.

·         About JProfiler
Shows general information about your copy of JProfiler and its license status.

 

 

 

 

 

1.         下载软件JProfile4.2.2(for windows版本)

2.         安装JProfileLicense使用如下信息

Name: License for You

Lincese Code: A-G667#42616F-10kg1r134fq9m#2217

 

http://blog.csdn.net/samlei/archive/2007/03/16/1531510.aspx

 

摘要:不当的O/R-Mapping框架使用,导致垃圾对象的生成。

 

最近用JProfile测试一个比较大的工程,希望能找到一些程序运行的瓶颈。过去使用Hibernate,很多人反映效率低。特别是懒加载关闭的时候,对象的持续生成最后会导致JVM直接OutOfMemory错误。目前使用iBatis,发现临时对象还是特别多,一开始百思不解。通过使用JProfile以后,终于找到了原因所在。

 

对象引用关系:baseView ->InstanceModel -> City

其中,baseView 引用了InstanceMode,而InstanceMode 引用了City对象,City对象是一个比较简单的对象,只有idname、中文名称等属性。在工程实际使用环境中,InstanceModel 是比较多的,可能会有数万经常被使用。通过对JVM堆的观察,发现每次InstanceModel对象生成的时候,都会附带出大量的City对象。由于一般应用中City的个数都有限,所以程序中专门对City对象作了缓存。为什么会产生大量City的临时对象呢?

通过在JProfile中查看堆的情况,可以很清楚的看到上述引用关系。这很正常啊?纳闷中,反复查看堆、对象、引用关系等信息,终于发现了线索。那就是,被引用的City对象中只有ID值,没有中文名称等其他信息。这就让我们找到了突破口,通过与开发工程师的交谈,被告知只使用了ID值,没有使用其他的属性。于是我们找到iBatis加载baseView对象的映射文件:

    <resultMap id="baseView" class="View">

               …

        <result column="CITYCODE"

            property="InstanceModel.city.id" jdbcType="NUMERIC"         />

    </resultMap>

注意,在上面这个定义文件中,加载View对象的时候,从同一张数据库表中,加载了View所属的City的代码(id)。但是iBatis框架在达到这个目的的同时,生成了一个临时City对象,并把ID赋了值。这就是原因!!

好了,原因找到了,优化的方案自然就出来了。只需要去掉InstanceModelCity对象的引用,直接取CityID就行了!再次运行JProfile,发现不再生成大量的City临时对象,优化的目的达到了。

 

结论:使用HibernateiBatis等框架的时候,我们过于热衷于对象引用的方便,忽视了这种方便的代价。有时候,我们只为了使用一个简单类型的数据,却大量加载肥胖对象而不自知。然后抱怨框架效率低,有问题。其实回头看看,良好的数据库设计、良好的对象设计这些基本的东西,是任何框架都不能帮我们做的。同时感叹JProfile这种强大工具给我们带来的好处,让我感觉又回到了DOS Debug 的时代。

 

你可能感兴趣的:(JProfile Beginning)