You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ni...@apache.org on 2019/06/29 17:13:26 UTC

[ignite] branch master updated: IGNITE-11941: VM metrics moved to GridMetricManager. (#6638)

This is an automated email from the ASF dual-hosted git repository.

nizhikov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new d0a7e45   IGNITE-11941: VM metrics moved to GridMetricManager. (#6638)
d0a7e45 is described below

commit d0a7e453be3495d7285c555c5a93561424f9b469
Author: Nikolay <ni...@apache.org>
AuthorDate: Sat Jun 29 20:13:14 2019 +0300

     IGNITE-11941: VM metrics moved to GridMetricManager. (#6638)
---
 .../managers/discovery/ClusterMetricsImpl.java     | 191 +++++++++++++--
 .../managers/discovery/GridDiscoveryManager.java   | 255 +-------------------
 .../managers/discovery/GridLocalMetrics.java       | 216 -----------------
 .../internal/processors/job/GridJobProcessor.java  |  10 +-
 .../processors/metric/GridMetricManager.java       | 268 +++++++++++++++++++++
 ...GridManagerMxBeanIllegalArgumentHandleTest.java |  22 +-
 .../cache/metric/SqlViewExporterSpiTest.java       |   6 +-
 .../processors/query/SqlSystemViewsSelfTest.java   |   1 -
 8 files changed, 455 insertions(+), 514 deletions(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/ClusterMetricsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/ClusterMetricsImpl.java
index 6525e65..b134e22 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/ClusterMetricsImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/ClusterMetricsImpl.java
@@ -17,6 +17,10 @@
 
 package org.apache.ignite.internal.managers.discovery;
 
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryUsage;
+import java.lang.management.RuntimeMXBean;
+import java.lang.management.ThreadMXBean;
 import java.util.Collection;
 import java.util.concurrent.TimeUnit;
 import org.apache.ignite.cluster.ClusterMetrics;
@@ -24,12 +28,29 @@ import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture;
 import org.apache.ignite.internal.processors.jobmetrics.GridJobMetrics;
+import org.apache.ignite.internal.processors.metric.GridMetricManager;
+import org.apache.ignite.internal.processors.metric.MetricRegistry;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.spi.metric.DoubleMetric;
+import org.apache.ignite.spi.metric.IntMetric;
+import org.apache.ignite.spi.metric.LongMetric;
+
+import static org.apache.ignite.internal.processors.metric.GridMetricManager.CPU_LOAD;
+import static org.apache.ignite.internal.processors.metric.GridMetricManager.DAEMON_THREAD_CNT;
+import static org.apache.ignite.internal.processors.metric.GridMetricManager.GC_CPU_LOAD;
+import static org.apache.ignite.internal.processors.metric.GridMetricManager.PEAK_THREAD_CNT;
+import static org.apache.ignite.internal.processors.metric.GridMetricManager.SYS_METRICS;
+import static org.apache.ignite.internal.processors.metric.GridMetricManager.THREAD_CNT;
+import static org.apache.ignite.internal.processors.metric.GridMetricManager.TOTAL_STARTED_THREAD_CNT;
+import static org.apache.ignite.internal.processors.metric.GridMetricManager.UP_TIME;
 
 /**
  * Cluster metrics proxy
  */
 public class ClusterMetricsImpl implements ClusterMetrics {
+    /** */
+    private static final RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
+
     /** Job metrics. */
     private volatile GridJobMetrics jobMetrics;
 
@@ -42,21 +63,139 @@ public class ClusterMetricsImpl implements ClusterMetrics {
     /** Kernel context. */
     private final GridKernalContext ctx;
 
-    /** VM Metrics. */
-    private final GridLocalMetrics vmMetrics;
-
     /** Node start time. */
     private final long nodeStartTime;
 
+    /** GC CPU load. */
+    private final DoubleMetric gcCpuLoad;
+
+    /** CPU load. */
+    private final DoubleMetric cpuLoad;
+
+    /** Up time. */
+    private final LongMetric upTime;
+
+    /** Available processors count. */
+    private final int availableProcessors;
+
+    /**
+     * Metric reflecting heap {@link MemoryUsage#getInit()}.
+     *
+     * @see GridMetricManager
+     */
+    private final LongMetric heapInit;
+
+    /**
+     * Metric reflecting heap {@link MemoryUsage#getUsed()}.
+     *
+     * @see GridMetricManager
+     */
+    private final LongMetric heapUsed;
+
+    /**
+     * Metric reflecting heap {@link MemoryUsage#getCommitted()}.
+     *
+     * @see GridMetricManager
+     */
+    private final LongMetric heapCommitted;
+
+    /**
+     * Metric reflecting heap {@link MemoryUsage#getMax()}.
+     *
+     * @see GridMetricManager
+     */
+    private final LongMetric heapMax;
+
+    /**
+     * Metric reflecting heap {@link MemoryUsage#getInit()}.
+     *
+     * @see GridMetricManager
+     */
+    private final LongMetric nonHeapInit;
+
+    /**
+     * Metric reflecting heap {@link MemoryUsage#getUsed()}.
+     *
+     * @see GridMetricManager
+     */
+    private final LongMetric nonHeapUsed;
+
+    /**
+     * Metric reflecting heap {@link MemoryUsage#getCommitted()}.
+     *
+     * @see GridMetricManager
+     */
+    private final LongMetric nonHeapCommitted;
+
+    /**
+     * Metric reflecting heap {@link MemoryUsage#getMax()}.
+     *
+     * @see GridMetricManager
+     */
+    private final LongMetric nonHeapMax;
+
+    /**
+     * Metric reflecting {@link ThreadMXBean#getThreadCount()}.
+     *
+     * @see GridMetricManager
+     */
+    private final IntMetric threadCnt;
+
+    /**
+     * Metric reflecting {@link ThreadMXBean#getPeakThreadCount()}.
+     *
+     * @see GridMetricManager
+     */
+    private final IntMetric peakThreadCnt;
+
+    /**
+     * Metric reflecting {@link ThreadMXBean#getTotalStartedThreadCount()}.
+     *
+     * @see GridMetricManager
+     */
+    private final LongMetric totalStartedThreadCnt;
+
+    /**
+     * Metric reflecting {@link ThreadMXBean#getDaemonThreadCount()}}.
+     *
+     * @see GridMetricManager
+     */
+    private final IntMetric daemonThreadCnt;
+
     /**
      * @param ctx Kernel context.
-     * @param vmMetrics VM metrics.
-     * @param nodeStartTime Node start time;
+     * @param nodeStartTime Node start time.
      */
-    public ClusterMetricsImpl(GridKernalContext ctx, GridLocalMetrics vmMetrics, long nodeStartTime) {
+    public ClusterMetricsImpl(GridKernalContext ctx, long nodeStartTime) {
         this.ctx = ctx;
-        this.vmMetrics = vmMetrics;
         this.nodeStartTime = nodeStartTime;
+
+        MetricRegistry mreg = ctx.metric().registry().withPrefix(SYS_METRICS);
+
+        gcCpuLoad = (DoubleMetric)mreg.findMetric(GC_CPU_LOAD);
+        cpuLoad = (DoubleMetric)mreg.findMetric(CPU_LOAD);
+        upTime = (LongMetric)mreg.findMetric(UP_TIME);
+
+        threadCnt = (IntMetric)mreg.findMetric(THREAD_CNT);
+        peakThreadCnt = (IntMetric)mreg.findMetric(PEAK_THREAD_CNT);
+        totalStartedThreadCnt = (LongMetric)mreg.findMetric(TOTAL_STARTED_THREAD_CNT);
+        daemonThreadCnt = (IntMetric)mreg.findMetric(DAEMON_THREAD_CNT);
+
+        availableProcessors = ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors();
+
+        MetricRegistry heap = mreg.withPrefix("memory", "heap");
+
+        heapInit = (LongMetric)heap.findMetric("init");
+        heapUsed = (LongMetric)heap.findMetric("used");
+        heapCommitted = (LongMetric)heap.findMetric("committed");
+        heapMax = (LongMetric)heap.findMetric("max");
+
+        MetricRegistry nonHeap = mreg.withPrefix("memory", "nonheap");
+
+        nonHeapInit = (LongMetric)nonHeap.findMetric("init");
+        nonHeapUsed = (LongMetric)nonHeap.findMetric("used");
+        nonHeapCommitted = (LongMetric)nonHeap.findMetric("committed");
+        nonHeapMax = (LongMetric)nonHeap.findMetric("max");
     }
 
     /** {@inheritDoc} */
@@ -206,12 +345,12 @@ public class ClusterMetricsImpl implements ClusterMetrics {
 
     /** {@inheritDoc} */
     @Override public int getTotalCpus() {
-        return vmMetrics.getAvailableProcessors();
+        return availableProcessors;
     }
 
     /** {@inheritDoc} */
     @Override public double getCurrentCpuLoad() {
-        return vmMetrics.getCurrentCpuLoad();
+        return cpuLoad.value();
     }
 
     /** {@inheritDoc} */
@@ -221,44 +360,44 @@ public class ClusterMetricsImpl implements ClusterMetrics {
 
     /** {@inheritDoc} */
     @Override public double getCurrentGcCpuLoad() {
-        return vmMetrics.getCurrentGcCpuLoad();
+        return gcCpuLoad.value();
     }
 
     /** {@inheritDoc} */
     @Override public long getHeapMemoryInitialized() {
-        return vmMetrics.getHeapMemoryInitialized();
+        return heapInit.value();
     }
 
     /** {@inheritDoc} */
     @Override public long getHeapMemoryUsed() {
-        return vmMetrics.getHeapMemoryUsed();
+        return heapUsed.value();
     }
 
     /** {@inheritDoc} */
     @Override public long getHeapMemoryCommitted() {
-        return vmMetrics.getHeapMemoryCommitted();
+        return heapCommitted.value();
     }
 
     /** {@inheritDoc} */
     @Override public long getHeapMemoryMaximum() {
-        return vmMetrics.getHeapMemoryMaximum();
+        return heapMax.value();
     }
 
     /** {@inheritDoc} */
     @Override public long getHeapMemoryTotal() {
-        return vmMetrics.getHeapMemoryMaximum();
+        return heapMax.value();
     }
 
     /** {@inheritDoc} */
     @Override public long getNonHeapMemoryInitialized() {
-        return vmMetrics.getNonHeapMemoryInitialized();
+        return nonHeapInit.value();
     }
 
     /** {@inheritDoc} */
     @Override public long getNonHeapMemoryUsed() {
         Collection<GridCacheAdapter<?, ?>> caches = ctx.cache().internalCaches();
 
-        long nonHeapUsed = vmMetrics.getNonHeapMemoryUsed();
+        long nonHeapUsed = this.nonHeapUsed.value();
 
         for (GridCacheAdapter<?, ?> cache : caches)
             if (cache.context().statisticsEnabled() && cache.context().started()
@@ -270,27 +409,27 @@ public class ClusterMetricsImpl implements ClusterMetrics {
 
     /** {@inheritDoc} */
     @Override public long getNonHeapMemoryCommitted() {
-        return vmMetrics.getNonHeapMemoryCommitted();
+        return nonHeapCommitted.value();
     }
 
     /** {@inheritDoc} */
     @Override public long getNonHeapMemoryMaximum() {
-        return vmMetrics.getNonHeapMemoryMaximum();
+        return nonHeapMax.value();
     }
 
     /** {@inheritDoc} */
     @Override public long getNonHeapMemoryTotal() {
-        return vmMetrics.getNonHeapMemoryMaximum();
+        return nonHeapMax.value();
     }
 
     /** {@inheritDoc} */
     @Override public long getUpTime() {
-        return vmMetrics.getUptime();
+        return upTime.value();
     }
 
     /** {@inheritDoc} */
     @Override public long getStartTime() {
-        return vmMetrics.getStartTime();
+        return rt.getStartTime();
     }
 
     /** {@inheritDoc} */
@@ -300,22 +439,22 @@ public class ClusterMetricsImpl implements ClusterMetrics {
 
     /** {@inheritDoc} */
     @Override public int getCurrentThreadCount() {
-        return vmMetrics.getThreadCount();
+        return threadCnt.value();
     }
 
     /** {@inheritDoc} */
     @Override public int getMaximumThreadCount() {
-        return vmMetrics.getPeakThreadCount();
+        return peakThreadCnt.value();
     }
 
     /** {@inheritDoc} */
     @Override public long getTotalStartedThreadCount() {
-        return vmMetrics.getTotalStartedThreadCount();
+        return totalStartedThreadCnt.value();
     }
 
     /** {@inheritDoc} */
     @Override public int getCurrentDaemonThreadCount() {
-        return vmMetrics.getDaemonThreadCount();
+        return daemonThreadCnt.value();
     }
 
     /** {@inheritDoc} */
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
index 27a33b9..4d894a1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
@@ -18,13 +18,6 @@
 package org.apache.ignite.internal.managers.discovery;
 
 import java.io.Serializable;
-import java.lang.management.GarbageCollectorMXBean;
-import java.lang.management.ManagementFactory;
-import java.lang.management.MemoryMXBean;
-import java.lang.management.MemoryUsage;
-import java.lang.management.OperatingSystemMXBean;
-import java.lang.management.RuntimeMXBean;
-import java.lang.management.ThreadMXBean;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -92,7 +85,6 @@ import org.apache.ignite.internal.processors.cluster.ChangeGlobalStateMessage;
 import org.apache.ignite.internal.processors.cluster.DiscoveryDataClusterState;
 import org.apache.ignite.internal.processors.cluster.IGridClusterStateProcessor;
 import org.apache.ignite.internal.processors.security.SecurityContext;
-import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor;
 import org.apache.ignite.internal.util.GridAtomicLong;
 import org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashMap;
 import org.apache.ignite.internal.util.GridSpinBusyLock;
@@ -165,7 +157,6 @@ import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_MARSHALLER_US
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_MARSHALLER_USE_DFLT_SUID;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_OFFHEAP_SIZE;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_PEER_CLASSLOADING;
-import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_PHY_RAM;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_SECURITY_COMPATIBILITY_MODE;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_USER_NAME;
 import static org.apache.ignite.internal.IgniteVersionUtils.VER;
@@ -177,24 +168,6 @@ import static org.apache.ignite.plugin.segmentation.SegmentationPolicy.NOOP;
  * Discovery SPI manager.
  */
 public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
-    /** Metrics update frequency. */
-    private static final long METRICS_UPDATE_FREQ = 3000;
-
-    /** JVM interface to memory consumption info */
-    private static final MemoryMXBean mem = ManagementFactory.getMemoryMXBean();
-
-    /** */
-    private static final OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean();
-
-    /** */
-    private static final RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
-
-    /** */
-    private static final ThreadMXBean threads = ManagementFactory.getThreadMXBean();
-
-    /** */
-    private static final Collection<GarbageCollectorMXBean> gc = ManagementFactory.getGarbageCollectorMXBeans();
-
     /** */
     private static final String PREFIX = "Topology snapshot";
 
@@ -271,18 +244,6 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
     /** Local node join to topology event. */
     private GridFutureAdapter<DiscoveryLocalJoinData> locJoin = new GridFutureAdapter<>();
 
-    /** GC CPU load. */
-    private volatile double gcCpuLoad;
-
-    /** CPU load. */
-    private volatile double cpuLoad;
-
-    /** Metrics. */
-    private final GridLocalMetrics metrics = createMetrics();
-
-    /** Metrics update worker. */
-    private GridTimeoutProcessor.CancelableTask metricsUpdateTask;
-
     /** Custom event listener. */
     private ConcurrentMap<Class<?>, List<CustomEventListener<DiscoveryCustomMessage>>> customEvtLsnrs =
         new ConcurrentHashMap<>();
@@ -316,43 +277,6 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
         super(ctx, ctx.config().getDiscoverySpi());
     }
 
-    /**
-     * @return Memory usage of non-heap memory.
-     */
-    private MemoryUsage nonHeapMemoryUsage() {
-        // Workaround of exception in WebSphere.
-        // We received the following exception:
-        // java.lang.IllegalArgumentException: used value cannot be larger than the committed value
-        // at java.lang.management.MemoryUsage.<init>(MemoryUsage.java:105)
-        // at com.ibm.lang.management.MemoryMXBeanImpl.getNonHeapMemoryUsageImpl(Native Method)
-        // at com.ibm.lang.management.MemoryMXBeanImpl.getNonHeapMemoryUsage(MemoryMXBeanImpl.java:143)
-        // at org.apache.ignite.spi.metrics.jdk.GridJdkLocalMetricsSpi.getMetrics(GridJdkLocalMetricsSpi.java:242)
-        //
-        // We so had to workaround this with exception handling, because we can not control classes from WebSphere.
-        try {
-            return mem.getNonHeapMemoryUsage();
-        }
-        catch (IllegalArgumentException ignored) {
-            return new MemoryUsage(0, 0, 0, 0);
-        }
-    }
-
-    /**
-     * Returns the current memory usage of the heap
-     * @return memory usage or fake value with zero in case there was exception during take of metrics
-     */
-    private MemoryUsage getHeapMemoryUsage() {
-        // Catch exception here to allow discovery proceed even if metrics are not available
-        // java.lang.IllegalArgumentException: committed = 5274103808 should be < max = 5274095616
-        // at java.lang.management.MemoryUsage.<init>(Unknown Source)
-        try {
-            return mem.getHeapMemoryUsage();
-        }
-        catch (IllegalArgumentException ignored) {
-            return new MemoryUsage(0, 0, 0, 0);
-        }
-    }
-
     /** {@inheritDoc} */
     @Override public void onBeforeSpiStart() {
         DiscoverySpi spi = getSpi();
@@ -501,16 +425,6 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
 
     /** {@inheritDoc} */
     @Override public void start() throws IgniteCheckedException {
-        long totSysMemory = -1;
-
-        try {
-            totSysMemory = U.<Long>property(os, "totalPhysicalMemorySize");
-        }
-        catch (RuntimeException ignored) {
-            // No-op.
-        }
-
-        ctx.addNodeAttribute(ATTR_PHY_RAM, totSysMemory);
         ctx.addNodeAttribute(ATTR_OFFHEAP_SIZE, requiredOffheap());
         ctx.addNodeAttribute(ATTR_DATA_REGIONS_OFFHEAP_SIZE, configuredOffheap());
 
@@ -543,8 +457,6 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
             checkSegmentOnStart();
         }
 
-        metricsUpdateTask = ctx.timeout().schedule(new MetricsUpdater(), METRICS_UPDATE_FREQ, METRICS_UPDATE_FREQ);
-
         spi.setMetricsProvider(createMetricsProvider());
 
         if (ctx.security().enabled()) {
@@ -1096,81 +1008,6 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
     }
 
     /**
-     * @return Metrics.
-     */
-    private GridLocalMetrics createMetrics() {
-        return new GridLocalMetrics() {
-            @Override public int getAvailableProcessors() {
-                return os.getAvailableProcessors();
-            }
-
-            @Override public double getCurrentCpuLoad() {
-                return cpuLoad;
-            }
-
-            @Override public double getCurrentGcCpuLoad() {
-                return gcCpuLoad;
-            }
-
-            @Override public long getHeapMemoryInitialized() {
-                return getHeapMemoryUsage().getInit();
-            }
-
-            @Override public long getHeapMemoryUsed() {
-                return getHeapMemoryUsage().getUsed();
-            }
-
-            @Override public long getHeapMemoryCommitted() {
-                return getHeapMemoryUsage().getCommitted();
-            }
-
-            @Override public long getHeapMemoryMaximum() {
-                return getHeapMemoryUsage().getMax();
-            }
-
-            @Override public long getNonHeapMemoryInitialized() {
-                return nonHeapMemoryUsage().getInit();
-            }
-
-            @Override public long getNonHeapMemoryUsed() {
-                return nonHeapMemoryUsage().getUsed();
-            }
-
-            @Override public long getNonHeapMemoryCommitted() {
-                return nonHeapMemoryUsage().getCommitted();
-            }
-
-            @Override public long getNonHeapMemoryMaximum() {
-                return nonHeapMemoryUsage().getMax();
-            }
-
-            @Override public long getUptime() {
-                return rt.getUptime();
-            }
-
-            @Override public long getStartTime() {
-                return rt.getStartTime();
-            }
-
-            @Override public int getThreadCount() {
-                return threads.getThreadCount();
-            }
-
-            @Override public int getPeakThreadCount() {
-                return threads.getPeakThreadCount();
-            }
-
-            @Override public long getTotalStartedThreadCount() {
-                return threads.getTotalStartedThreadCount();
-            }
-
-            @Override public int getDaemonThreadCount() {
-                return threads.getDaemonThreadCount();
-            }
-        };
-    }
-
-    /**
      * @return Metrics provider.
      */
     public DiscoveryMetricsProvider createMetricsProvider() {
@@ -1184,7 +1021,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
 
             /** {@inheritDoc} */
             @Override public ClusterMetrics metrics() {
-                return new ClusterMetricsImpl(ctx, metrics, startTime);
+                return new ClusterMetricsImpl(ctx, startTime);
             }
 
             /** {@inheritDoc} */
@@ -1220,13 +1057,6 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
         };
     }
 
-    /**
-     * @return Local metrics.
-     */
-    public GridLocalMetrics metrics() {
-        return metrics;
-    }
-
     /** @return {@code True} if ordering is supported. */
     private boolean discoOrdered() {
         DiscoverySpiOrderSupport ann = U.getAnnotation(ctx.config().getDiscoverySpi().getClass(),
@@ -1728,9 +1558,6 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
         // Stop receiving notifications.
         getSpi().setListener(null);
 
-        // Stop discovery worker and metrics updater.
-        U.closeQuiet(metricsUpdateTask);
-
         U.cancel(discoWrk);
 
         U.join(discoWrk, log);
@@ -3159,86 +2986,6 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
         }
     }
 
-    /**
-     *
-     */
-    private class MetricsUpdater implements Runnable {
-        /** */
-        private long prevGcTime = -1;
-
-        /** */
-        private long prevCpuTime = -1;
-
-        /** {@inheritDoc} */
-        @Override public void run() {
-            gcCpuLoad = getGcCpuLoad();
-            cpuLoad = getCpuLoad();
-        }
-
-        /**
-         * @return GC CPU load.
-         */
-        private double getGcCpuLoad() {
-            long gcTime = 0;
-
-            for (GarbageCollectorMXBean bean : gc) {
-                long colTime = bean.getCollectionTime();
-
-                if (colTime > 0)
-                    gcTime += colTime;
-            }
-
-            gcTime /= metrics.getAvailableProcessors();
-
-            double gc = 0;
-
-            if (prevGcTime > 0) {
-                long gcTimeDiff = gcTime - prevGcTime;
-
-                gc = (double)gcTimeDiff / METRICS_UPDATE_FREQ;
-            }
-
-            prevGcTime = gcTime;
-
-            return gc;
-        }
-
-        /**
-         * @return CPU load.
-         */
-        private double getCpuLoad() {
-            long cpuTime;
-
-            try {
-                cpuTime = U.<Long>property(os, "processCpuTime");
-            }
-            catch (IgniteException ignored) {
-                return -1;
-            }
-
-            // Method reports time in nanoseconds across all processors.
-            cpuTime /= 1000000 * metrics.getAvailableProcessors();
-
-            double cpu = 0;
-
-            if (prevCpuTime > 0) {
-                long cpuTimeDiff = cpuTime - prevCpuTime;
-
-                // CPU load could go higher than 100% because calculating of cpuTimeDiff also takes some time.
-                cpu = Math.min(1.0, (double)cpuTimeDiff / METRICS_UPDATE_FREQ);
-            }
-
-            prevCpuTime = cpuTime;
-
-            return cpu;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return S.toString(MetricsUpdater.class, this, super.toString());
-        }
-    }
-
     /** Discovery topology future. */
     private static class DiscoTopologyFuture extends GridFutureAdapter<Long> implements GridLocalEventListener {
         /** */
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridLocalMetrics.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridLocalMetrics.java
deleted file mode 100644
index ff7cba2..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridLocalMetrics.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.managers.discovery;
-
-import java.io.Serializable;
-
-/**
- * This class represents runtime information available for current VM.
- */
-public interface GridLocalMetrics extends Serializable {
-    /**
-     * Returns the number of processors available to the Java virtual machine.
-     * This method is equivalent to the {@link Runtime#availableProcessors()}
-     * method.
-     * <p> This value may change during a particular invocation of
-     * the virtual machine.
-     *
-     * @return The number of processors available to the virtual
-     *      machine; never smaller than one.
-     */
-    public int getAvailableProcessors();
-
-    /**
-     * Returns the system load average for the last minute.
-     * The system load average is the sum of the number of runnable entities
-     * queued to the {@linkplain #getAvailableProcessors available processors}
-     * and the number of runnable entities running on the available processors
-     * averaged over a period of time.
-     * The way in which the load average is calculated is operating system
-     * specific but is typically a damped time-dependent average.
-     * <p>
-     * If the load average is not available, a negative value is returned.
-     * <p>
-     * This method is designed to provide a hint about the system load
-     * and may be queried frequently. The load average may be unavailable on
-     * some platform where it is expensive to implement this method.
-     *
-     * @return The system load average; or a negative value if not available.
-     */
-    public double getCurrentCpuLoad();
-
-    /**
-     * Returns amount of time spent in GC since the last update.
-     * <p>
-     * The return value is a percentage of time.
-     *
-     * @return Amount of time, spent in GC since the last update.
-     */
-    public double getCurrentGcCpuLoad();
-
-    /**
-     * Returns the amount of heap memory in bytes that the Java virtual machine
-     * initially requests from the operating system for memory management.
-     * This method returns {@code -1} if the initial memory size is undefined.
-     * <p>
-     * This value represents a setting of the heap memory for Java VM and is
-     * not a sum of all initial heap values for all memory pools.
-     *
-     * @return The initial size of memory in bytes; {@code -1} if undefined.
-     */
-    public long getHeapMemoryInitialized();
-
-    /**
-     * Returns the current heap size that is used for object allocation.
-     * The heap consists of one or more memory pools. This value is
-     * the sum of {@code used} heap memory values of all heap memory pools.
-     * <p>
-     * The amount of used memory in the returned is the amount of memory
-     * occupied by both live objects and garbage objects that have not
-     * been collected, if any.
-     *
-     * @return Amount of heap memory used.
-     */
-    public long getHeapMemoryUsed();
-
-    /**
-     * Returns the amount of heap memory in bytes that is committed for
-     * the Java virtual machine to use. This amount of memory is
-     * guaranteed for the Java virtual machine to use.
-     * The heap consists of one or more memory pools. This value is
-     * the sum of {@code committed} heap memory values of all heap memory pools.
-     *
-     * @return The amount of committed memory in bytes.
-     */
-    public long getHeapMemoryCommitted();
-
-    /**
-     * Returns the maximum amount of heap memory in bytes that can be
-     * used for memory management. This method returns {@code -1}
-     * if the maximum memory size is undefined.
-     * <p>
-     * This amount of memory is not guaranteed to be available
-     * for memory management if it is greater than the amount of
-     * committed memory.  The Java virtual machine may fail to allocate
-     * memory even if the amount of used memory does not exceed this
-     * maximum size.
-     * <p>
-     * This value represents a setting of the heap memory for Java VM and is
-     * not a sum of all initial heap values for all memory pools.
-     *
-     * @return The maximum amount of memory in bytes; {@code -1} if undefined.
-     */
-    public long getHeapMemoryMaximum();
-
-    /**
-     * Returns the amount of non-heap memory in bytes that the Java virtual machine
-     * initially requests from the operating system for memory management.
-     * This method returns {@code -1} if the initial memory size is undefined.
-     * <p>
-     * This value represents a setting of non-heap memory for Java VM and is
-     * not a sum of all initial heap values for all memory pools.
-     *
-     * @return The initial size of memory in bytes; {@code -1} if undefined.
-     */
-    public long getNonHeapMemoryInitialized();
-
-    /**
-     * Returns the current non-heap memory size that is used by Java VM.
-     * The non-heap memory consists of one or more memory pools. This value is
-     * the sum of {@code used} non-heap memory values of all non-heap memory pools.
-     *
-     * @return Amount of none-heap memory used.
-     */
-    public long getNonHeapMemoryUsed();
-
-    /**
-     * Returns the amount of non-heap memory in bytes that is committed for
-     * the Java virtual machine to use. This amount of memory is
-     * guaranteed for the Java virtual machine to use.
-     * The non-heap memory consists of one or more memory pools. This value is
-     * the sum of {@code committed} non-heap memory values of all non-heap memory pools.
-     *
-     * @return The amount of committed memory in bytes.
-     */
-    public long getNonHeapMemoryCommitted();
-
-    /**
-     * Returns the maximum amount of non-heap memory in bytes that can be
-     * used for memory management. This method returns {@code -1}
-     * if the maximum memory size is undefined.
-     * <p>
-     * This amount of memory is not guaranteed to be available
-     * for memory management if it is greater than the amount of
-     * committed memory. The Java virtual machine may fail to allocate
-     * memory even if the amount of used memory does not exceed this
-     * maximum size.
-     * <p>
-     * This value represents a setting of the non-heap memory for Java VM and is
-     * not a sum of all initial non-heap values for all memory pools.
-     *
-     * @return The maximum amount of memory in bytes; {@code -1} if undefined.
-     */
-    public long getNonHeapMemoryMaximum();
-
-    /**
-     * Returns the uptime of the Java virtual machine in milliseconds.
-     *
-     * @return Uptime of the Java virtual machine in milliseconds.
-     */
-    public long getUptime();
-
-    /**
-     * Returns the start time of the Java virtual machine in milliseconds.
-     * This method returns the approximate time when the Java virtual
-     * machine started.
-     *
-     * @return Start time of the Java virtual machine in milliseconds.
-     */
-    public long getStartTime();
-
-    /**
-     * Returns the current number of live threads including both
-     * daemon and non-daemon threads.
-     *
-     * @return the current number of live threads.
-     */
-    public int getThreadCount();
-
-    /**
-     * Returns the peak live thread count since the Java virtual machine
-     * started or peak was reset.
-     *
-     * @return The peak live thread count.
-     */
-    public int getPeakThreadCount();
-
-    /**
-     * Returns the total number of threads created and also started
-     * since the Java virtual machine started.
-     *
-     * @return The total number of threads started.
-     */
-    public long getTotalStartedThreadCount();
-
-    /**
-     * Returns the current number of live daemon threads.
-     *
-     * @return The current number of live daemon threads.
-     */
-    public int getDaemonThreadCount();
-}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobProcessor.java
index 751377f..8652e98 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobProcessor.java
@@ -86,6 +86,7 @@ import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.marshaller.Marshaller;
+import org.apache.ignite.spi.metric.DoubleMetric;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentLinkedHashMap;
@@ -104,6 +105,8 @@ import static org.apache.ignite.internal.GridTopic.TOPIC_TASK;
 import static org.apache.ignite.internal.managers.communication.GridIoPolicy.MANAGEMENT_POOL;
 import static org.apache.ignite.internal.managers.communication.GridIoPolicy.SYSTEM_POOL;
 import static org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState.OWNING;
+import static org.apache.ignite.internal.processors.metric.GridMetricManager.CPU_LOAD;
+import static org.apache.ignite.internal.processors.metric.GridMetricManager.SYS_METRICS;
 import static org.apache.ignite.internal.processors.metric.impl.MetricUtils.metricName;
 import static org.jsr166.ConcurrentLinkedHashMap.QueuePolicy.PER_SEGMENT_Q;
 
@@ -205,6 +208,9 @@ public class GridJobProcessor extends GridProcessorAdapter {
     @Deprecated
     private final LongAdder finishedJobsTime = new LongAdder();
 
+    /** Cpu load metric */
+    private final DoubleMetric cpuLoadMetric;
+
     /** Maximum job execution time for finished jobs. */
     @Deprecated
     private final GridAtomicLong maxFinishedJobsTime = new GridAtomicLong();
@@ -296,6 +302,8 @@ public class GridJobProcessor extends GridProcessorAdapter {
         jobExecLsnr = new JobExecutionListener();
         discoLsnr = new JobDiscoveryListener();
 
+        cpuLoadMetric = (DoubleMetric)ctx.metric().registry().findMetric(metricName(SYS_METRICS, CPU_LOAD));
+
         MetricRegistry mreg = ctx.metric().registry().withPrefix(JOBS);
 
         startedJobsMetric = mreg.metric(STARTED, "Number of started jobs.");
@@ -1079,7 +1087,7 @@ public class GridJobProcessor extends GridProcessorAdapter {
             m.setMaximumExecutionTime(maxFinishedTime);
 
         // CPU load.
-        m.setCpuLoad(ctx.discovery().metrics().getCurrentCpuLoad());
+        m.setCpuLoad(cpuLoadMetric.value());
 
         ctx.jobMetric().addSnapshot(m);
     }
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/metric/GridMetricManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/metric/GridMetricManager.java
index e7e2640..bf35639 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/metric/GridMetricManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/metric/GridMetricManager.java
@@ -17,20 +17,36 @@
 
 package org.apache.ignite.internal.processors.metric;
 
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.MemoryUsage;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.management.RuntimeMXBean;
+import java.lang.management.ThreadMXBean;
+import java.util.Collection;
 import java.util.Map;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.RejectedExecutionHandler;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.ThreadPoolExecutor;
 import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.managers.GridManagerAdapter;
+import org.apache.ignite.internal.processors.metric.impl.DoubleMetricImpl;
+import org.apache.ignite.internal.processors.metric.impl.LongMetricImpl;
+import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor;
 import org.apache.ignite.internal.util.StripedExecutor;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.spi.metric.MetricExporterSpi;
 import org.apache.ignite.thread.IgniteStripedThreadPoolExecutor;
 import org.jetbrains.annotations.Nullable;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_PHY_RAM;
+import static org.apache.ignite.internal.processors.metric.impl.MetricUtils.metricName;
 
 /**
  * This manager should provide {@link MetricRegistry} for each configured {@link MetricExporterSpi}.
@@ -85,9 +101,66 @@ public class GridMetricManager extends GridManagerAdapter<MetricExporterSpi> {
     /** Group for a thread pools. */
     public static final String THREAD_POOLS = "threadPools";
 
+    /** Metrics update frequency. */
+    private static final long METRICS_UPDATE_FREQ = 3000;
+
+    /** System metrics prefix. */
+    public static final String SYS_METRICS = "sys";
+
+    /** GC CPU load metric name. */
+    public static final String GC_CPU_LOAD = "GcCpuLoad";
+
+    /** CPU load metric name. */
+    public static final String CPU_LOAD = "CpuLoad";
+
+    /** Up time metric name. */
+    public static final String UP_TIME = "UpTime";
+
+    /** Thread count metric name. */
+    public static final String THREAD_CNT = "ThreadCount";
+
+    /** Peak thread count metric name. */
+    public static final String PEAK_THREAD_CNT = "PeakThreadCount";
+
+    /** Total started thread count metric name. */
+    public static final String TOTAL_STARTED_THREAD_CNT = "TotalStartedThreadCount";
+
+    /** Daemon thread count metric name. */
+    public static final String DAEMON_THREAD_CNT = "DaemonThreadCount";
+
+    /** JVM interface to memory consumption info */
+    private static final MemoryMXBean mem = ManagementFactory.getMemoryMXBean();
+
+    /** */
+    private static final OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean();
+
+    /** */
+    private static final RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
+
+    /** */
+    private static final ThreadMXBean threads = ManagementFactory.getThreadMXBean();
+
+    /** */
+    private static final Collection<GarbageCollectorMXBean> gc = ManagementFactory.getGarbageCollectorMXBeans();
+
     /** Monitoring registry. */
     private MetricRegistry mreg;
 
+    /** Metrics update worker. */
+    private GridTimeoutProcessor.CancelableTask metricsUpdateTask;
+
+    /** GC CPU load. */
+    private final DoubleMetricImpl gcCpuLoad;
+
+    /** CPU load. */
+    private final DoubleMetricImpl cpuLoad;
+
+    /** Heap memory metrics. */
+    private final MemoryUsageMetrics heap;
+
+    /** Nonheap memory metrics. */
+    private final MemoryUsageMetrics nonHeap;
+
     /**
      * @param ctx Kernal context.
      */
@@ -95,6 +168,33 @@ public class GridMetricManager extends GridManagerAdapter<MetricExporterSpi> {
         super(ctx, ctx.config().getMetricExporterSpi());
 
         mreg = new MetricRegistryImpl(ctx.log(MetricRegistryImpl.class));
+
+        ctx.addNodeAttribute(ATTR_PHY_RAM, totalSysMemory());
+
+        heap = new MemoryUsageMetrics(metricName(SYS_METRICS, "memory", "heap"));
+        nonHeap = new MemoryUsageMetrics(metricName(SYS_METRICS, "memory", "nonheap"));
+
+        heap.update(mem.getHeapMemoryUsage());
+        nonHeap.update(mem.getNonHeapMemoryUsage());
+
+        MetricRegistry sysreg = mreg.withPrefix(SYS_METRICS);
+
+        gcCpuLoad = sysreg.doubleMetric(GC_CPU_LOAD, "GC CPU load.");
+        cpuLoad = sysreg.doubleMetric(CPU_LOAD, "CPU load.");
+
+        sysreg.register("SystemLoadAverage", os::getSystemLoadAverage, Double.class, null);
+        sysreg.register(UP_TIME, rt::getUptime, null);
+        sysreg.register(THREAD_CNT, threads::getThreadCount, null);
+        sysreg.register(PEAK_THREAD_CNT, threads::getPeakThreadCount, null);
+        sysreg.register(TOTAL_STARTED_THREAD_CNT, threads::getTotalStartedThreadCount, null);
+        sysreg.register(DAEMON_THREAD_CNT, threads::getDaemonThreadCount, null);
+        sysreg.register("CurrentThreadCpuTime", threads::getCurrentThreadCpuTime, null);
+        sysreg.register("CurrentThreadUserTime", threads::getCurrentThreadUserTime, null);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void onKernalStart0() throws IgniteCheckedException {
+        metricsUpdateTask = ctx.timeout().schedule(new MetricsUpdater(), METRICS_UPDATE_FREQ, METRICS_UPDATE_FREQ);
     }
 
     /** {@inheritDoc} */
@@ -108,6 +208,9 @@ public class GridMetricManager extends GridManagerAdapter<MetricExporterSpi> {
     /** {@inheritDoc} */
     @Override public void stop(boolean cancel) throws IgniteCheckedException {
         stopSpi();
+
+        // Stop discovery worker and metrics updater.
+        U.closeQuiet(metricsUpdateTask);
     }
 
     /**
@@ -290,4 +393,169 @@ public class GridMetricManager extends GridManagerAdapter<MetricExporterSpi> {
             int[].class,
             "Size of queue per stripe.");
     }
+
+    /**
+     * @return Memory usage of non-heap memory.
+     */
+    public MemoryUsage nonHeapMemoryUsage() {
+        // Workaround of exception in WebSphere.
+        // We received the following exception:
+        // java.lang.IllegalArgumentException: used value cannot be larger than the committed value
+        // at java.lang.management.MemoryUsage.<init>(MemoryUsage.java:105)
+        // at com.ibm.lang.management.MemoryMXBeanImpl.getNonHeapMemoryUsageImpl(Native Method)
+        // at com.ibm.lang.management.MemoryMXBeanImpl.getNonHeapMemoryUsage(MemoryMXBeanImpl.java:143)
+        // at org.apache.ignite.spi.metrics.jdk.GridJdkLocalMetricsSpi.getMetrics(GridJdkLocalMetricsSpi.java:242)
+        //
+        // We so had to workaround this with exception handling, because we can not control classes from WebSphere.
+        try {
+            return mem.getNonHeapMemoryUsage();
+        }
+        catch (IllegalArgumentException ignored) {
+            return new MemoryUsage(0, 0, 0, 0);
+        }
+    }
+
+    /**
+     * Returns the current memory usage of the heap.
+     * @return Memory usage or fake value with zero in case there was exception during take of metrics.
+     */
+    public MemoryUsage heapMemoryUsage() {
+        // Catch exception here to allow discovery proceed even if metrics are not available
+        // java.lang.IllegalArgumentException: committed = 5274103808 should be < max = 5274095616
+        // at java.lang.management.MemoryUsage.<init>(Unknown Source)
+        try {
+            return mem.getHeapMemoryUsage();
+        }
+        catch (IllegalArgumentException ignored) {
+            return new MemoryUsage(0, 0, 0, 0);
+        }
+    }
+
+    /**
+     * @return Total system memory.
+     */
+    private long totalSysMemory() {
+        try {
+            return U.<Long>property(os, "totalPhysicalMemorySize");
+        }
+        catch (RuntimeException ignored) {
+            return -1;
+        }
+    }
+
+    /** */
+    private class MetricsUpdater implements Runnable {
+        /** */
+        private long prevGcTime = -1;
+
+        /** */
+        private long prevCpuTime = -1;
+
+        /** {@inheritDoc} */
+        @Override public void run() {
+            heap.update(heapMemoryUsage());
+            nonHeap.update(nonHeapMemoryUsage());
+
+            gcCpuLoad.value(getGcCpuLoad());
+            cpuLoad.value(getCpuLoad());
+        }
+
+        /**
+         * @return GC CPU load.
+         */
+        private double getGcCpuLoad() {
+            long gcTime = 0;
+
+            for (GarbageCollectorMXBean bean : gc) {
+                long colTime = bean.getCollectionTime();
+
+                if (colTime > 0)
+                    gcTime += colTime;
+            }
+
+            gcTime /= os.getAvailableProcessors();
+
+            double gc = 0;
+
+            if (prevGcTime > 0) {
+                long gcTimeDiff = gcTime - prevGcTime;
+
+                gc = (double)gcTimeDiff / METRICS_UPDATE_FREQ;
+            }
+
+            prevGcTime = gcTime;
+
+            return gc;
+        }
+
+        /**
+         * @return CPU load.
+         */
+        private double getCpuLoad() {
+            long cpuTime;
+
+            try {
+                cpuTime = U.<Long>property(os, "processCpuTime");
+            }
+            catch (IgniteException ignored) {
+                return -1;
+            }
+
+            // Method reports time in nanoseconds across all processors.
+            cpuTime /= 1000000 * os.getAvailableProcessors();
+
+            double cpu = 0;
+
+            if (prevCpuTime > 0) {
+                long cpuTimeDiff = cpuTime - prevCpuTime;
+
+                // CPU load could go higher than 100% because calculating of cpuTimeDiff also takes some time.
+                cpu = Math.min(1.0, (double)cpuTimeDiff / METRICS_UPDATE_FREQ);
+            }
+
+            prevCpuTime = cpuTime;
+
+            return cpu;
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(MetricsUpdater.class, this, super.toString());
+        }
+    }
+
+    /** Memory usage metrics. */
+    public class MemoryUsageMetrics {
+        /** @see MemoryUsage#getInit() */
+        private final LongMetricImpl init;
+
+        /** @see MemoryUsage#getUsed() */
+        private final LongMetricImpl used;
+
+        /** @see MemoryUsage#getCommitted() */
+        private final LongMetricImpl committed;
+
+        /** @see MemoryUsage#getMax() */
+        private final LongMetricImpl max;
+
+        /**
+         * @param prefix Metric prefix.
+         */
+        public MemoryUsageMetrics(String prefix) {
+            MetricRegistry mreg = GridMetricManager.this.mreg.withPrefix(prefix);
+
+            this.init = mreg.metric("init", null);
+            this.used = mreg.metric("used", null);
+            this.committed = mreg.metric("committed", null);
+            this.max = mreg.metric("max", null);
+        }
+
+        /** Updates metric to the provided values. */
+        public void update(MemoryUsage usage) {
+            init.value(usage.getInit());
+            used.value(usage.getUsed());
+            committed.value(usage.getCommitted());
+            max.value(usage.getMax());
+        }
+    }
 }
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/managers/GridManagerMxBeanIllegalArgumentHandleTest.java b/modules/core/src/test/java/org/apache/ignite/internal/managers/GridManagerMxBeanIllegalArgumentHandleTest.java
index 7e0caa9..691c2e2 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/managers/GridManagerMxBeanIllegalArgumentHandleTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/managers/GridManagerMxBeanIllegalArgumentHandleTest.java
@@ -24,8 +24,8 @@ import java.lang.reflect.Modifier;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.GridKernalContext;
-import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.internal.processors.metric.GridMetricManager;
+import org.apache.ignite.spi.metric.noop.NoopMetricExporterSpi;
 import org.jetbrains.annotations.NotNull;
 import org.junit.After;
 import org.junit.Before;
@@ -43,10 +43,10 @@ import static org.mockito.Mockito.when;
  * Test modifies static final field, used only for development
  */
 public class GridManagerMxBeanIllegalArgumentHandleTest {
-    /** Original value of {@link GridDiscoveryManager#mem} to be restored after test */
+    /** Original value of {@link GridMetricManager#mem} to be restored after test */
     private Object mxBeanToRestore;
 
-    /** Mem mx bean field in {@link GridDiscoveryManager#mem}, already set accessible */
+    /** Mem mx bean field in {@link GridMetricManager#mem}, already set accessible */
     private Field memMxBeanField;
 
     /** If we succeeded to set final field this flag is true, otherwise test assertions will not be performed */
@@ -82,9 +82,9 @@ public class GridManagerMxBeanIllegalArgumentHandleTest {
     }
 
 
-    /** Reflections {@link GridDiscoveryManager#mem} field which was made accessible and mutable */
+    /** Reflections {@link GridMetricManager#mem} field which was made accessible and mutable */
     @NotNull private Field createAccessibleMemField() throws NoSuchFieldException, IllegalAccessException {
-        final Field memField = GridDiscoveryManager.class.getDeclaredField("mem");
+        final Field memField = GridMetricManager.class.getDeclaredField("mem");
         memField.setAccessible(true);
 
         final Field modifiersField = Field.class.getDeclaredField("modifiers");
@@ -94,7 +94,7 @@ public class GridManagerMxBeanIllegalArgumentHandleTest {
     }
 
     /**
-     * Restores static field in {@link GridDiscoveryManager#mem}
+     * Restores static field in {@link GridMetricManager#mem}
      *
      * @throws Exception if field set failed
      */
@@ -108,7 +108,7 @@ public class GridManagerMxBeanIllegalArgumentHandleTest {
     @Test
     public void testIllegalStateIsCatch() {
         final IgniteConfiguration cfg = new IgniteConfiguration();
-        cfg.setDiscoverySpi(new TcpDiscoverySpi());
+        cfg.setMetricExporterSpi(new NoopMetricExporterSpi());
 
         final IgniteLogger log = Mockito.mock(IgniteLogger.class);
 
@@ -117,12 +117,12 @@ public class GridManagerMxBeanIllegalArgumentHandleTest {
         when(ctx.log(Mockito.anyString())).thenReturn(log);
         when(ctx.log(Mockito.any(Class.class))).thenReturn(log);
 
-        final GridDiscoveryManager mgr = new GridDiscoveryManager(ctx);
-        final long nHeapMax = mgr.metrics().getNonHeapMemoryMaximum();
+        final GridMetricManager mgr = new GridMetricManager(ctx);
+        final long nHeapMax = mgr.nonHeapMemoryUsage().getMax();
         if (correctSetupOfTestPerformed)
             assertEquals(0, nHeapMax);
 
-        final long heapMax = mgr.metrics().getHeapMemoryMaximum();
+        final long heapMax = mgr.heapMemoryUsage().getMax();
         if (correctSetupOfTestPerformed)
             assertEquals(0, heapMax);
     }
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/metric/SqlViewExporterSpiTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/metric/SqlViewExporterSpiTest.java
index f41cba6..1c30673 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/metric/SqlViewExporterSpiTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/metric/SqlViewExporterSpiTest.java
@@ -86,7 +86,6 @@ public class SqlViewExporterSpiTest extends AbstractExporterSpiTest {
             names.add((String)row.get(0));
 
             assertNotNull(row.get(1));
-            assertNotNull(row.get(2));
         }
 
         for (String attr : EXPECTED_ATTRIBUTES)
@@ -109,12 +108,9 @@ public class SqlViewExporterSpiTest extends AbstractExporterSpiTest {
 
         Set<IgniteBiTuple<String, String>> vals = new HashSet<>();
 
-        for (List<?> row : res) {
+        for (List<?> row : res)
             vals.add(t((String)row.get(0), (String)row.get(1)));
 
-            assertNotNull(row.get(2));
-        }
-
         assertEquals(expVals, vals);
     }
 
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlSystemViewsSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlSystemViewsSelfTest.java
index 711b068..c278792 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlSystemViewsSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlSystemViewsSelfTest.java
@@ -1466,7 +1466,6 @@ public class SqlSystemViewsSelfTest extends AbstractIndexingCommonTest {
         public MockedClusterMetrics(ClusterMetricsImpl original) throws Exception {
             super(
                 getField(original, "ctx"),
-                getField(original, "vmMetrics"),
                 getField(original, "nodeStartTime"));
         }