cxf-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Chester Kim (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (CXF-6642) Memory Leak in ResponseImpl.readEntity()
Date Wed, 14 Oct 2015 22:01:05 GMT

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

Chester Kim updated CXF-6642:
-----------------------------
    Description: 
Massive number of ResponseImpl instances are not garbage collected after calling readEntity.
 By looking at VisualVM, it seems like those are indirectly referred by something stored in
ThreadLocal which is used by context resolving and never been removed after all.   Our production
instance actually caused OutOfMemory errors after this.   It might be related to https://issues.apache.org/jira/browse/CXF-6458
and looks simiar to https://java.net/jira/browse/JERSEY-2463 but not sure.  Note this only
happens when I used thread pool.
My workaround was bypassing readEntity() and deal with inputstream directly like following
which is not quite desirable but works for now.
{code}
    private static Response copy(Response response) {
        return Optional.ofNullable(response)
                .map(r -> r.getEntity())
                .filter(e -> e instanceof InputStream)
                .map(is -> readResponse(response.getStatus(), (InputStream)is))
                .orElse(response);
    }

    private static Response readResponse(int status, InputStream is) {
        Response response = Response.serverError().build();
        try {
            String payload = IOUtils.toString(is);
            response = Response.status(status).entity(payload).build();
        } catch (IOException e) {
            log.error("Failed to read entity from response", e);
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                log.error("Failed to close InputStream after reading entity from response",
e);
            }
        }
        return response;
    }
{code}

  was:
Massive number of ResponseImpl instances are not garbage collected after calling readEntity.
 By looking at VisualVM, it seems like those are indirectly referred by something stored in
ThreadLocal which is used by context resolving and never been removed after all.   Our production
instance actually caused OutOfMemory errors after this.   It might be related to https://issues.apache.org/jira/browse/CXF-6458
and looks simiar to https://java.net/jira/browse/JERSEY-2463 but not sure.
My workaround was bypassing readEntity() and deal with inputstream directly like following
which is not quite desirable but works for now.
{code}
    private static Response copy(Response response) {
        return Optional.ofNullable(response)
                .map(r -> r.getEntity())
                .filter(e -> e instanceof InputStream)
                .map(is -> readResponse(response.getStatus(), (InputStream)is))
                .orElse(response);
    }

    private static Response readResponse(int status, InputStream is) {
        Response response = Response.serverError().build();
        try {
            String payload = IOUtils.toString(is);
            response = Response.status(status).entity(payload).build();
        } catch (IOException e) {
            log.error("Failed to read entity from response", e);
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                log.error("Failed to close InputStream after reading entity from response",
e);
            }
        }
        return response;
    }
{code}


> Memory Leak in ResponseImpl.readEntity()
> ----------------------------------------
>
>                 Key: CXF-6642
>                 URL: https://issues.apache.org/jira/browse/CXF-6642
>             Project: CXF
>          Issue Type: Bug
>          Components: JAX-RS
>    Affects Versions: 3.1.2, 3.1.3
>         Environment: Mac OS X 10.10.5, Spring 4.2.0
>            Reporter: Chester Kim
>            Priority: Critical
>              Labels: client, cxf
>
> Massive number of ResponseImpl instances are not garbage collected after calling readEntity.
 By looking at VisualVM, it seems like those are indirectly referred by something stored in
ThreadLocal which is used by context resolving and never been removed after all.   Our production
instance actually caused OutOfMemory errors after this.   It might be related to https://issues.apache.org/jira/browse/CXF-6458
and looks simiar to https://java.net/jira/browse/JERSEY-2463 but not sure.  Note this only
happens when I used thread pool.
> My workaround was bypassing readEntity() and deal with inputstream directly like following
which is not quite desirable but works for now.
> {code}
>     private static Response copy(Response response) {
>         return Optional.ofNullable(response)
>                 .map(r -> r.getEntity())
>                 .filter(e -> e instanceof InputStream)
>                 .map(is -> readResponse(response.getStatus(), (InputStream)is))
>                 .orElse(response);
>     }
>     private static Response readResponse(int status, InputStream is) {
>         Response response = Response.serverError().build();
>         try {
>             String payload = IOUtils.toString(is);
>             response = Response.status(status).entity(payload).build();
>         } catch (IOException e) {
>             log.error("Failed to read entity from response", e);
>         } finally {
>             try {
>                 is.close();
>             } catch (IOException e) {
>                 log.error("Failed to close InputStream after reading entity from response",
e);
>             }
>         }
>         return response;
>     }
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message