[ 
https://issues.apache.org/jira/browse/CASSANDRA-20446?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Dmitry Konstantinov updated CASSANDRA-20446:
--------------------------------------------
    Description: 
Currently we construct javax.management.ObjectName when we publish our metrics 
via JMX by concatenating key/value pairs and providing the result to ObjectName 
constructor:

org.apache.cassandra.metrics.CassandraMetricsRegistry.MetricName#MetricName(...)
{code:java}
public MetricName(String group, String type, String name, String scope)
{
    this(group, type, name, scope, createMBeanName(group, type, name, scope));
}

private static String createMBeanName(String group, String type, String name, 
String scope)
{
    final StringBuilder nameBuilder = new StringBuilder();
    nameBuilder.append(ObjectName.quote(group));
    nameBuilder.append(":type=");
    nameBuilder.append(ObjectName.quote(type));
    if (scope != null)
    {
        nameBuilder.append(",scope=");
        nameBuilder.append(ObjectName.quote(scope));
    }
    if (name.length() > 0)
    {
        nameBuilder.append(",name=");
        nameBuilder.append(ObjectName.quote(name));
    }
    return nameBuilder.toString();
} 
{code}
{code}
public ObjectName getMBeanName()
{

    String mname = mBeanName;

    if (mname == null)
        mname = getMetricName();

    try
    {

        return new ObjectName(mname);
    } catch (MalformedObjectNameException e)
    {
        try
        {
            return new ObjectName(ObjectName.quote(mname));
        } catch (MalformedObjectNameException e1)
        {
            throw new RuntimeException(e1);
        }
    }
}
{code}
later javax.management.ObjectName parses and splits this concatenated name back 
to fill internal _propertyList map.
As a result we get a lot of small duplicated property name/value String objects 
(like: "scope", "name", "<some metric name>", "<some table name>" stored within 
JMX repository.
I have found this issue during an analysis of memory usage for a dev instance 
of Cassandra (4.1 + JDK 11) where we want to have memory usage to be small to 
reduce cost of dev envs.
There are 275 tables for the instance (including all system ones), it has 
395MiB heap used and about 52MiB from them are consumed by 
com.sun.jmx.mbeanserver.JmxMBeanServer, where about 41 MiB is spent for 
ObjectName objects (a big percent, and the second major contributor to memory 
usage after heap memtables):

!image-2025-03-17-18-14-01-628.png|width=400! 
!image-2025-03-17-18-14-48-658.png|width=400!

The possible way to reduce this _propertyList duplication is to use another 
constructor to build ObjectName: ObjectName(String domain, Hashtable<String, 
String> table) and provide the properties as a map within 
org.apache.cassandra.metrics.CassandraMetricsRegistry.MetricName#getMBeanName 
logic, in this way we can avoid the String duplicates in properties across the 
ObjectName instances. 

  was:
Currently we construct javax.management.ObjectName when we publish our metrics 
via JMX by concatenating key/value pairs and providing the result to ObjectName 
constructor:

org.apache.cassandra.metrics.CassandraMetricsRegistry.MetricName#MetricName(...)
{code:java}
public MetricName(String group, String type, String name, String scope)
{
    this(group, type, name, scope, createMBeanName(group, type, name, scope));
}

private static String createMBeanName(String group, String type, String name, 
String scope)
{
    final StringBuilder nameBuilder = new StringBuilder();
    nameBuilder.append(ObjectName.quote(group));
    nameBuilder.append(":type=");
    nameBuilder.append(ObjectName.quote(type));
    if (scope != null)
    {
        nameBuilder.append(",scope=");
        nameBuilder.append(ObjectName.quote(scope));
    }
    if (name.length() > 0)
    {
        nameBuilder.append(",name=");
        nameBuilder.append(ObjectName.quote(name));
    }
    return nameBuilder.toString();
} 
{code}
{code}
public ObjectName getMBeanName()
{

    String mname = mBeanName;

    if (mname == null)
        mname = getMetricName();

    try
    {

        return new ObjectName(mname);
    } catch (MalformedObjectNameException e)
    {
        try
        {
            return new ObjectName(ObjectName.quote(mname));
        } catch (MalformedObjectNameException e1)
        {
            throw new RuntimeException(e1);
        }
    }
}
{code}
later javax.management.ObjectName parses and splits this concatenated name back 
to fill internal _propertyList map.
As a result we get a lot of small duplicated property name/value String objects 
(like: "scope", "name", "<some metric name>", "<some table name>" stored within 
JMX repository.
I have found this issue during an analysis of memory usage for a dev instance 
of Cassandra (4.1 + JDK 11) where we want to have memory usage to be small to 
reduce cost of dev envs.
There are 275 tables for the instance (including all system ones), it has 
395MiB heap used and about 52MiB from them are consumed by 
com.sun.jmx.mbeanserver.JmxMBeanServer, where about 41 MiB is spent for 
ObjectName objects (a big percent, and the second major contributor to memory 
used after heap memtables):

!image-2025-03-17-18-14-01-628.png|width=400! 
!image-2025-03-17-18-14-48-658.png|width=400!

The possible way to reduce this _propertyList duplication is to use another 
constructor to build ObjectName: ObjectName(String domain, Hashtable<String, 
String> table) and provide the properties as a map within 
org.apache.cassandra.metrics.CassandraMetricsRegistry.MetricName#getMBeanName 
logic, in this way we can avoid the String duplicates in properties across the 
ObjectName instances. 


> Reduce level of duplication for properties in JMX ObjectName for metrics
> ------------------------------------------------------------------------
>
>                 Key: CASSANDRA-20446
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-20446
>             Project: Apache Cassandra
>          Issue Type: Improvement
>          Components: Observability/JMX
>            Reporter: Dmitry Konstantinov
>            Priority: Normal
>         Attachments: image-2025-03-17-18-14-01-628.png, 
> image-2025-03-17-18-14-48-658.png
>
>
> Currently we construct javax.management.ObjectName when we publish our 
> metrics via JMX by concatenating key/value pairs and providing the result to 
> ObjectName constructor:
> org.apache.cassandra.metrics.CassandraMetricsRegistry.MetricName#MetricName(...)
> {code:java}
> public MetricName(String group, String type, String name, String scope)
> {
>     this(group, type, name, scope, createMBeanName(group, type, name, scope));
> }
> private static String createMBeanName(String group, String type, String name, 
> String scope)
> {
>     final StringBuilder nameBuilder = new StringBuilder();
>     nameBuilder.append(ObjectName.quote(group));
>     nameBuilder.append(":type=");
>     nameBuilder.append(ObjectName.quote(type));
>     if (scope != null)
>     {
>         nameBuilder.append(",scope=");
>         nameBuilder.append(ObjectName.quote(scope));
>     }
>     if (name.length() > 0)
>     {
>         nameBuilder.append(",name=");
>         nameBuilder.append(ObjectName.quote(name));
>     }
>     return nameBuilder.toString();
> } 
> {code}
> {code}
> public ObjectName getMBeanName()
> {
>     String mname = mBeanName;
>     if (mname == null)
>         mname = getMetricName();
>     try
>     {
>         return new ObjectName(mname);
>     } catch (MalformedObjectNameException e)
>     {
>         try
>         {
>             return new ObjectName(ObjectName.quote(mname));
>         } catch (MalformedObjectNameException e1)
>         {
>             throw new RuntimeException(e1);
>         }
>     }
> }
> {code}
> later javax.management.ObjectName parses and splits this concatenated name 
> back to fill internal _propertyList map.
> As a result we get a lot of small duplicated property name/value String 
> objects (like: "scope", "name", "<some metric name>", "<some table name>" 
> stored within JMX repository.
> I have found this issue during an analysis of memory usage for a dev instance 
> of Cassandra (4.1 + JDK 11) where we want to have memory usage to be small to 
> reduce cost of dev envs.
> There are 275 tables for the instance (including all system ones), it has 
> 395MiB heap used and about 52MiB from them are consumed by 
> com.sun.jmx.mbeanserver.JmxMBeanServer, where about 41 MiB is spent for 
> ObjectName objects (a big percent, and the second major contributor to memory 
> usage after heap memtables):
> !image-2025-03-17-18-14-01-628.png|width=400! 
> !image-2025-03-17-18-14-48-658.png|width=400!
> The possible way to reduce this _propertyList duplication is to use another 
> constructor to build ObjectName: ObjectName(String domain, Hashtable<String, 
> String> table) and provide the properties as a map within 
> org.apache.cassandra.metrics.CassandraMetricsRegistry.MetricName#getMBeanName 
> logic, in this way we can avoid the String duplicates in properties across 
> the ObjectName instances. 



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to