private void updateJmxCache() {
        boolean getAllMetrics = false;
        synchronized (this) {
            if (System.currentTimeMillis() - jmxCacheTS >= jmxCacheTTL) {
                // temporarilly advance the expired while updating the cache
                jmxCacheTS = System.currentTimeMillis() + jmxCacheTTL;
                if (lastRecs == null) {
                    getAllMetrics = true;
                }
            } else {
                return;
            }
        }

        if (getAllMetrics) {
            MetricsBuilderImpl builder = new MetricsBuilderImpl();
            getMetrics(builder, true);
        }

        synchronized (this) {
            int cacheSize = attrCache.size(); // because updateAttrCache changes it!
            int numMetrics = updateAttrCache();
            if (cacheSize < numMetrics) {
                updateInfoCache();
            }
            jmxCacheTS = System.currentTimeMillis();
            lastRecs = null;
        }
    }