Unused JAVA constants and memory usage

Hi,

We are working with the Matter and Zigbee protocols, these protocols define lot of elements (cluster, attributes, enums …)

They also provide a tool (ZAP) that can be used to generate code based on templates files that we define ourself.

Now the question is about memory consumption when building with MicroEJ:

If we have constants defined in a class, but some constants are not used anywhere in the code, did they take FLASH space when the image is built ?

For exemple:

// Enum for AttributeWritePermission
public static final int EMBER_ZCL_ATTRIBUTE_WRITE_PERMISSION_DENY_WRITE               = 0;
public static final int EMBER_ZCL_ATTRIBUTE_WRITE_PERMISSION_ALLOW_WRITE_NORMAL       = 1;
public static final int EMBER_ZCL_ATTRIBUTE_WRITE_PERMISSION_ALLOW_WRITE_OF_READ_ONLY = 2;
public static final int EMBER_ZCL_ATTRIBUTE_WRITE_PERMISSION_UNSUPPORTED_ATTRIBUTE    = 134;
public static final int EMBER_ZCL_ATTRIBUTE_WRITE_PERMISSION_INVALID_VALUE            = 135;
public static final int EMBER_ZCL_ATTRIBUTE_WRITE_PERMISSION_READ_ONLY                = 136;
public static final int EMBER_ZCL_ATTRIBUTE_WRITE_PERMISSION_INVALID_DATA_TYPE        = 141;

// Enum for BarrierControlBarrierPosition
public static final int EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED  = 0;
public static final int EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN    = 100;
public static final int EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_UNKNOWN = 255;

// Enum for BarrierControlMovingState
public static final int EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED = 0;
public static final int EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_CLOSING = 1;
public static final int EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_OPENING = 2;

Some response from a JAVA SE chat

16:42 < Tyaku> Hi, We are developping an application for Matter, There are lot of clusters, enum attributes informations. And there is a tool to generate code based on templates. Our application will be 
               used in embedded system, so it's important to keep the flash/ram usage very minimal. My question is: In JAVA if we declare variables like this:  "public static final int 
               ATTRIBUTE_WRITE_PERMISSION_DENY_WRITE = 0;", if these 
16:42 < Tyaku> variables are **NOT** used. Did they take "flash" space when converted to bytecode ? 
16:44 < Tyaku> For example, with languages like C, the compiler is able to remove "dead code" so it is not integrated in the "binary". Is it the same with JAVA
16:44 < sbeex1> an enum enumerates accepted values for a given name. So I would expect the JVM to include them in the code (your jar can be integrated into other jars as dependency and so on that would 
                be bad if they disappeared because you didn't use them in your API
16:44 < Maldivia> Tyaku: are you building .class files running on a JVM, or are you doing native-builds (like with Graal for instance) ?
16:45 < Tyaku> In my case the idea is to have a file with a lot of generated constant but to use only some of them when needed. 
16:45 < Maldivia> Tyaku: they *will* take space in a .class file, and when those classes are loaded -- for native compilation, well, they are likely eliminated, but that would be something to ask in a 
                  GraalVM forum
16:45 < Tyaku> I am using MicroEJ JVM 
16:46 < Tyaku> Ok, In my case to MicroEJ JVM forum. 
16:46 < Maldivia> I would assume it doesn't eliminate it, and it will be present in mem
16:47 < Maldivia> (unless the JVM can verify that you never use reflection, or load new classes etc, it's hard to eliminate fields like that)
16:47 -!- collinm [~collinm@modemcable156.40-177-173.mc.videotron.ca] has quit [Ping timeout: 268 seconds]
16:47 < Maldivia> a closed-world compilation, which a native-build does, is meant to eliminated exactly those things
16:48 < sbeex1> yes... a very "hard coded way" would be to pass it via your CI and then do some code parsing in your build check if constants are used -> if not then remove it from the enum, then 
                recompile the whole thing but yeah.. kind of exotic
16:48 -!- mihael [~mihael@user/mihael] has quit [Quit: Client closed]
16:49 < sbeex1> (or in a bash script whatever.. btw)
16:50 < Maldivia> Tyaku: ProGuard might also be able to eliminate it, if you minify/obfuscate the compiled classes

Hi @marvelous,

A Java static of primitive type (e.g. int) and declared with the final keyword is directly inline in the code where it is used.

This is done by the Java compiler, not related to the JVM implementation.

Constants in Java go in the classfile Constant Pool (more information about that here https://blogs.oracle.com/javamagazine/post/java-class-file-constant-pool).

In our case, classfiles are pre-processed by SOAR which only embeds what is required in the final executable.

Therefore declaring any Java member (type, method or static field) that is not used by the code will not consume neither FLASH nor RAM space on the target device.

Hope it helps,

–Frédéric