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

E90870-01

coherence/lang/HeapAnalyzer.hpp

00001 /*
00002 * HeapAnalyzer.hpp
00003 *
00004 * Copyright (c) 2000, 2019, 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 "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 toString
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         /**
00135          * Return the number of objects which have been marked as uncollectable.
00136          *
00137          * Return the number of objects which have been marked as uncollectable.
00138          */
00139         virtual int64_t getImmortalCount() const = 0;
00140 
00141     protected:
00142         /**
00143         * Register a newly created Object with the system.
00144         *
00145         * This method is called automatically by coherence::lang::Object once
00146         * the Object has finished construction.
00147         *
00148         * @param o  the newly created Object.
00149         */
00150         virtual void registerObject(const Object& o) = 0;
00151 
00152         /**
00153         * Unregister an Object with the system.
00154         *
00155         * This method is called automatically by coherence::lang::Object
00156         * just prior to the deletion of the Object.  No new handles or views
00157         * may be created to the object.
00158         *
00159         * @param o  the Object to unregister
00160         */
00161         virtual void unregisterObject(const Object& o) = 0;
00162 
00163         /**
00164          * Invoked when an object is deemed to immortal and can never be collected.
00165          *
00166          * Note the specified object will have already been registered via registerObject.
00167          */
00168         virtual void registerImmortal(const Object& o) = 0;
00169 
00170 
00171     // ----- static helper methods ------------------------------------------
00172 
00173     public:
00174         /**
00175         * Ensure that the delta between the current heap and the supplied
00176         * snapshot is as expected.
00177         *
00178         * This method can be used to perform quick memory leak assertions.
00179         *
00180         * @code
00181         * HeapAnalyzer::Snapshot::View vSnapStart = HeapAnalyzer::ensureHeap();
00182         *   ...
00183         *   ...
00184         * HeapAnalyzer::ensureHeap(vSnapStart);
00185         * @endcode
00186         *
00187         * @param vSnap   the snapshot to ensure; or NULL for return only
00188         * @param cDelta  the allowable change in the heap's object count
00189         *
00190         * @return a new Snapshot
00191         *
00192         * @throws IllegalStateException if the delta does not contain the
00193         *         expected amount. The text of the exception will include the
00194         *         output of the Snapshots toString() method.
00195         */
00196         static Snapshot::View ensureHeap(Snapshot::View vSnap = NULL,
00197                 int64_t cDelta = 0);
00198 
00199 
00200     // ----- inner class: Block ---------------------------------------------
00201 
00202     public:
00203         /**
00204          * The HeapAnalyzer::Block allows for easily verifying that a block
00205          * of code does not leak memory.
00206          *
00207          * @code
00208          * COH_ENSURE_HEAP
00209          *    {
00210          *    ... // your code here
00211          *    }
00212          * @endcode
00213          */
00214         class Block
00215             {
00216             // ----- constructors ---------------------------------------
00217 
00218             public:
00219                 /**
00220                 * Construct a ZeroBlock object.
00221                 *
00222                 * This will automatically capture an initial snapshot
00223                 */
00224                 Block()
00225                     : m_vSnap(ensureHeap())
00226                     {
00227                     }
00228 
00229                 /**
00230                 * Copy constructor for COH_ENSURE_HEAP macro.
00231                 */
00232                 Block(const Block& that)
00233                     : m_vSnap(that.m_vSnap)
00234                     {
00235                     that.m_vSnap = NULL;
00236                     }
00237 
00238                 /**
00239                 * Destroy a Block object.
00240                 *
00241                 * This will test that no memory has been leaked
00242                 */
00243                 ~Block() COH_NOEXCEPT(false)
00244                     {
00245                     ensureHeap(m_vSnap);
00246                     }
00247 
00248 
00249             // ----- operators ------------------------------------------
00250 
00251             public:
00252                 /*
00253                 * Boolean conversion for use in COH_ENSURE_HEAP macro.
00254                 *
00255                 * @return false if snapshot is held, true otherwise
00256                 */
00257                 operator bool() const
00258                     {
00259                     return m_vSnap == NULL;
00260                     }
00261 
00262             private:
00263                 /**
00264                 * Blocked assignment operator.
00265                 */
00266                 const Block& operator=(const Block&);
00267 
00268                 /**
00269                 * Blocked dynamic allocation.
00270                 */
00271                 static void* operator new(size_t);
00272 
00273 
00274             // ----- data members ---------------------------------------
00275 
00276             protected:
00277                 mutable Snapshot::View m_vSnap; // on stack
00278             };
00279 
00280     // ----- friends --------------------------------------------------------
00281 
00282     friend class Object;
00283     };
00284 
00285 COH_CLOSE_NAMESPACE2
00286 
00287 
00288 /**
00289 * Macro for making more readable HeapAnalyzer::Block code blocks See the
00290 * documentation of Block for a usage example.
00291 *
00292 * @see coherence::lang::HeapAnalyzer::Block
00293 */
00294 #define COH_ENSURE_HEAP \
00295     if (coherence::lang::HeapAnalyzer::Block COH_UNIQUE_IDENTIFIER(_coh_heap_) \
00296         = coherence::lang::HeapAnalyzer::Block()) \
00297         { \
00298         COH_THROW(coherence::lang::IllegalStateException::create()); \
00299         } \
00300     else
00301 
00302 
00303 #endif // COH_HEAP_ANALYZER_HPP
Copyright © 2000, 2019, Oracle and/or its affiliates. All rights reserved.