[jboss-jira] [JBoss JIRA] (WFLY-12446) Memory leak in StatelessSessionComponent

Matěj Novotný (Jira) issues at jboss.org
Wed Sep 11 07:25:02 EDT 2019


    [ https://issues.jboss.org/browse/WFLY-12446?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13782798#comment-13782798 ] 

Matěj Novotný commented on WFLY-12446:
--------------------------------------

Alright, I think I see the issue -  *doesn't look like a bug but a user error* . Like I said above, when you retrieve {{@Dependent}} instances via {{Instance}}, you need to keep reference to them and destroy them. Note that every invocation of {{Instance.get()}} gives you new, different instance of the bean that you need to destroy and a for cycle over {{Instance}} means you invoke {{get()}} in order to grab each of those beans.
Therefore in the following code(from example), two sets of {{Command}} instances are created but only one is destroyed (mind the NOTEs I added to the code):

{code}
public CommandResult executeCommand(String commandName, String parameter) {

        CommandResult result = null;

        logger.infof("CommandService: searching for command -> %s", commandName);

        if (commands != null) {

            // search command
            for (Command command : commands) {

                // NOTE - this instantiates the command beans but no destroy is invoked within this for cycle!

                String name = command.getName();
                logger.infof("   ... %s", name);

                // execute if found
                if (commandName.equals(name)) {

                    logger.infof("   ... found command, executing %s", name);
                    result = command.execute(name + ": " + parameter);

                    break;
                } 
            }

            // command found?
            if (result == null) {
                logger.infof("CommandService: command not found -> %s", commandName);
                result = new CommandResult(0L, "Undefined");
            }

            // avoid memory leak
            logger.info("destroying commands to avoid memory leak!");
            for (Command command : commands) {
                // NOTE - this is redundant, it created new/different instances of Command and destroys those only!
                commands.destroy(command);
            }

        } else {
            logger.info("CommandService: no commands available!");
        }

        return result;
    }
{code}

You can fix this easily by changing the first for cycle as follows and dropping the second one:

{code}
            for (Command command : commands) {

                String name = command.getName();
                logger.infof("   ... %s", name);

                // execute if found
                if (commandName.equals(name)) {

                    logger.infof("   ... found command, executing %s", name);
                    result = command.execute(name + ": " + parameter);

                    // destroy the instance
                    commands.destroy(command);
                    break;
                }  else {
                    // destroy the instance
                    commands.destroy(command);
                }
            }
{code}

Fixing the code like this, jconsole shows me much less memory used during the load test and especially not hanging around afterwards.

> Memory leak in StatelessSessionComponent
> ----------------------------------------
>
>                 Key: WFLY-12446
>                 URL: https://issues.jboss.org/browse/WFLY-12446
>             Project: WildFly
>          Issue Type: Bug
>          Components: CDI / Weld, EJB
>    Affects Versions: 17.0.1.Final
>            Reporter: Joerg Baesner
>            Assignee: Cheng Fang
>            Priority: Major
>         Attachments: dump-weld.png, playground-jee8.zip, server.log.gz, wfly-12446-heap-dump.png
>
>
> When running the attached reproducer application and doing a memory analysis afterwards, it looks like a memory leak, e. g.
> {code}
> One instance of "org.jboss.as.ejb3.component.stateless.StatelessSessionComponent" loaded by "org.jboss.modules.ModuleClassLoader @ 0x5e0fbc2e0" occupies 936,593,520 (96.13%) bytes. The memory is accumulated in one instance of "java.util.concurrent.ConcurrentLinkedQueue$Node" loaded by "<system class loader>".
> {code}



--
This message was sent by Atlassian Jira
(v7.13.5#713005)



More information about the jboss-jira mailing list