Oracle® Fusion Middleware C++ API Reference for Oracle Coherence
12c (12.1.3.0.0)

E47891-01

coherence/lang/HeapAnalyzer.hpp

00001 /*
00002 * HeapAnalyzer.hpp
00003 *
00004 * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
00005 *
00006 * Oracle is a registered trademarks of Oracle Corporation and/or its
00007 * affiliates.
00008 *
00009 * This software is the confidential and proprietary information of Oracle
00010 * Corporation. You shall not disclose such confidential and proprietary
00011 * information and shall use it only in accordance with the terms of the
00012 * license agreement you entered into with Oracle.
00013 *
00014 * This notice may not be removed or altered.
00015 */
00016 #ifndef COH_HEAP_ANALYZER_HPP
00017 #define COH_HEAP_ANALYZER_HPP
00018 
00019 #include "coherence/lang/interface_spec.hpp"
00020 #include "coherence/lang/Object.hpp"
00021 #include "coherence/lang/TypedHandle.hpp"
00022 
00023 COH_OPEN_NAMESPACE2(coherence,lang)
00024 
00025 
00026 /**
00027 * HeapAnalyzer provides a base diagnostics interface for tracking heap usage.
00028 *
00029 * There is at most one HeapAnalyzer registered with the system for the
00030 * lifetime of the process. The HeapAnalyzer implementation may be specified
00031 * via the "tangosol.coherence.heap.analyzer" system property. The property
00032 * can be set to one of the following values:
00033 * <ul>
00034 *  <li>none      No heap analysis will be performed.</li>
00035 *  <li>object    The coherence::lang::ObjectCountHeapAnalyzer will be used.</li>
00036 *  <li>class     The coherence::lang::ClassBasedHeapAnalyzer will be used.</li>
00037 *  <li>alloc     The coherence::lang::ClassBasedHeapAnalyzer will be used,
00038 *                in allocation analysis mode.</li>
00039 *  <li>[custom]  The name of a class registered with the SystemClassLoader.</li>
00040 * </ul>
00041 *
00042 * In the case where a custom class is specified, it must implement this
00043 * interface.  The custom analyzer will be initialized as soon as the class
00044 * is registered with the SystemClassLoader. As static initialization order
00045 * cannot be guaranteed, this custom analyzer will not be notified of managed
00046 * objects created earlier in the static initialization order.
00047 *
00048 * The active analyzer may be obtained from the System::getHeapAnalyzer()
00049 * method.
00050 *
00051 * The HeapAnalyzer and Snapshot interfaces are intentionally narrow.
00052 * Implementations are expected to provide useful information via the toStream
00053 * method, as well as by possibly augmenting the interfaces. The minimal
00054 * interface is sufficient for detecting memory leaks.
00055 *
00056 * HeapAnalyzer::Snapshot::View vSnap = hAnalyzer->capture();
00057 *   ...
00058 *   ...
00059 * std::cout << "Heap changed by: " << hAnalyzer->delta(vSnap) << std::endl;
00060 *
00061 * @see ObjectCountHeapAnalyzer
00062 * @see ClassBasedHeapAnalyzer
00063 *
00064 * @author mf  2008.04.27
00065 */
00066 class COH_EXPORT HeapAnalyzer
00067     : public interface_spec<HeapAnalyzer>
00068     {
00069     // ----- nested interface: Snapshot -------------------------------------
00070 
00071     public:
00072         /**
00073         * Snapshot provides a abstract mechanism for comparing successive
00074         * heap analysis points.
00075         */
00076         class COH_EXPORT Snapshot
00077             : public interface_spec<Snapshot>
00078             {
00079             // ----- Snapshot interface ---------------------------------
00080 
00081             public:
00082                 /**
00083                 * Return the number of registered objects reflected by this
00084                 * snapshot.
00085                 *
00086                 * @return the number of registered objects
00087                 */
00088                 virtual int64_t getObjectCount() const = 0;
00089 
00090                 /**
00091                 * Return the result of "subtracting" the supplied Snapshot
00092                 * from this Snapshot.
00093                 *
00094                 * @param vThat  the snapshot to compare against
00095                 *
00096                 * @return the delta between two snapshots
00097                 */
00098                 virtual Snapshot::View delta(Snapshot::View vThat) const = 0;
00099             };
00100 
00101 
00102     // ----- HeapAnalyzer interface -----------------------------------------
00103 
00104     public:
00105         /**
00106         * Capture a Snapshot of the current state of the heap.
00107         *
00108         * Note, when performing captures in a loop, and assigning the captured
00109         * snapshot to a handle referencing a snapshot, it is advisable to
00110         * NULL out the handle first, so as to avoid the new snapshot including
00111         * the "cost" of snapshot it is about to replace.
00112         *
00113         * @return a Snapshot of the current state of the heap.
00114         */
00115         virtual Snapshot::View capture() const = 0;
00116 
00117         /**
00118         * Compute the delta between the supplied Snapshot and the current heap
00119         * state.
00120         *
00121         * @param vThat  the snapshot to compare against.
00122         *
00123         * @return a snapshot containing the delta
00124         */
00125         virtual Snapshot::View delta(Snapshot::View vThat) const = 0;
00126 
00127         /**
00128         * Return the number of registered objects.
00129         *
00130         * @return the number of registered objects
00131         */
00132         virtual int64_t getObjectCount() const = 0;
00133 
00134     protected:
00135         /**
00136         * Register a newly created Object with the system.
00137         *
00138         * This method is called automatically by coherence::lang::Object once
00139         * the Object has finished construction.
00140         *
00141         * @param o  the newly created Object.
00142         */
00143         virtual void registerObject(const Object& o) = 0;
00144 
00145         /**
00146         * Unregister an Object with the system.
00147         *
00148         * This method is called automatically by coherence::lang::Object
00149         * just prior to the deletion of the Object.  No new handles or views
00150         * may be created to the object.
00151         *
00152         * @param o  the Object to unregister
00153         */
00154         virtual void unregisterObject(const Object& o) = 0;
00155 
00156 
00157     // ----- static helper methods ------------------------------------------
00158 
00159     public:
00160         /**
00161         * Ensure that the delta between the current heap and the supplied
00162         * snapshot is as expected.
00163         *
00164         * This method can be used to perform quick memory leak assertions.
00165         *
00166         * @code
00167         * HeapAnalyzer::Snapshot::View vSnapStart = HeapAnalyzer::ensureHeap();
00168         *   ...
00169         *   ...
00170         * HeapAnalyzer::ensureHeap(vSnapStart);
00171         * @endcode
00172         *
00173         * @param vSnap   the snapshot to ensure; or NULL for return only
00174         * @param cDelta  the allowable change in the heap's object count
00175         *
00176         * @return a new Snapshot
00177         *
00178         * @throws IllegalStateException if the delta does not contain the
00179         *         expected amount. The text of the exception will include the
00180         *         output of the Snapshots toStream() method.
00181         */
00182         static Snapshot::View ensureHeap(Snapshot::View vSnap = NULL,
00183                 int64_t cDelta = 0);
00184 
00185 
00186     // ----- inner class: Block ---------------------------------------------
00187 
00188     public:
00189         /**
00190          * The HeapAnalyzer::Block allows for easily verifying that a block
00191          * of code does not leak memory.
00192          *
00193          * @code
00194          * COH_ENSURE_HEAP
00195          *    {
00196          *    ... // your code here
00197          *    }
00198          * @endcode
00199          */
00200         class Block
00201             {
00202             // ----- constructors ---------------------------------------
00203 
00204             public:
00205                 /**
00206                 * Construct a ZeroBlock object.
00207                 *
00208                 * This will automatically capture an initial snapshot
00209                 */
00210                 Block()
00211                     : m_vSnap(ensureHeap())
00212                     {
00213                     }
00214 
00215                 /**
00216                 * Copy constructor for COH_ENSURE_HEAP macro.
00217                 */
00218                 Block(const Block& that)
00219                     : m_vSnap(that.m_vSnap)
00220                     {
00221                     that.m_vSnap = NULL;
00222                     }
00223 
00224                 /**
00225                 * Destroy a Block object.
00226                 *
00227                 * This will test that no memory has been leaked
00228                 */
00229                 ~Block()
00230                     {
00231                     ensureHeap(m_vSnap);
00232                     }
00233 
00234 
00235             // ----- operators ------------------------------------------
00236 
00237             public:
00238                 /*
00239                 * Boolean conversion for use in COH_ENSURE_HEAP macro.
00240                 *
00241                 * @return false if snapshot is held, true otherwise
00242                 */
00243                 operator bool() const
00244                     {
00245                     return m_vSnap == NULL;
00246                     }
00247 
00248             private:
00249                 /**
00250                 * Blocked assignment operator.
00251                 */
00252                 const Block& operator=(const Block&);
00253 
00254                 /**
00255                 * Blocked dynamic allocation.
00256                 */
00257                 static void* operator new(size_t);
00258 
00259 
00260             // ----- data members ---------------------------------------
00261 
00262             protected:
00263                 mutable Snapshot::View m_vSnap; // on stack
00264             };
00265 
00266     // ----- friends --------------------------------------------------------
00267 
00268     friend class Object;
00269     };
00270 
00271 COH_CLOSE_NAMESPACE2
00272 
00273 
00274 /**
00275 * Macro for making more readable HeapAnalyzer::Block code blocks See the
00276 * documentation of Block for a usage example.
00277 *
00278 * @see coherence::lang::HeapAnalyzer::Block
00279 */
00280 #define COH_ENSURE_HEAP \
00281     if (coherence::lang::HeapAnalyzer::Block COH_UNIQUE_IDENTIFIER(_coh_heap_) \
00282         = coherence::lang::HeapAnalyzer::Block()) \
00283         { \
00284         COH_THROW(coherence::lang::IllegalStateException::create()); \
00285         } \
00286     else
00287 
00288 
00289 #endif // COH_HEAP_ANALYZER_HPP
Copyright © 2000, 2014, Oracle and/or its affiliates. All rights reserved.