2016-06-08 3 views
0

CXF Component/s: Bus, JAX-RSCXF - Fuite de mémoire se produit si un bus configuré avec les fournisseurs est utilisé par les clients par demande

Affecte Version/s: 3.1.0, 3.1. 6

Environnement: Redhat Enterprise Linux (Santiago), OpenJDK 7, Tomcat 7

Nous avons une application avec des composants REST client pour faire des appels vers les services Web backend. Au cours de notre test de performance de routine, l'outil JProfiler affiche de nombreuses entrées de propriétés de bus (avec les clés nommées "bus.providers.set.") Renseignées lors de la création d'instances de ClientProviderFactory. Ces entrées de propriétés de bus semblent rester en tas pendant toute la durée de l'exécution de 6 heures. En effet, environ 100 000 entrées occupent 13 Mo de tas. En bref, GC ne semble pas se produire assez fréquemment pour maintenir l'utilisation du tas dans les limites.

Est-ce une sorte de bug ou un manque de configuration nécessaire dans CXF pour optimiser la création/nettoyage de ces objets?

Répondre

0

Le problème concerné semble provenir de a defect in CXF où les entrées ProviderFactory hashCode sont remplies sur l'instance de bus si des clients par requête sont utilisés. Ainsi, si vous avez effectué N appels depuis le démarrage de l'application, N nombre d'entrées seront remplies. Par conséquent, il occupe un énorme tas JVM et ne reçoit pas de GC, à temps et conduit à des problèmes de performance. Bien que le correctif CXF pour le défaut soit disponible dans les versions d'instantanés - 3.1.7 et 3.2.0, vous pouvez utiliser le correctif de contournement suivant si vous êtes bloqué avec CXF 3.1.6 ou plus ancien. Il fonctionne comme un charme.

code Java

public class PurgeFactoryHashcodeInterceptor extends AbstractPhaseInterceptor<Message> { 

    public PurgeFactoryHashcodeInterceptor() { 

     super(Phase.PREPARE_SEND); 
     addBefore(MessageSenderInterceptor.class.getName()); 
    } 

    @Override 
    public void handleMessage(Message message) throws Fault { 

      cleanUpBusProperties(); 
    } 

    @Override 
    public void handleFault(Message message) throws Fault { 

      cleanUpBusProperties(); 
    } 

    private void cleanUpBusProperties() { 

     Bus bus = SpringContextProvider.getApplicationContext().getBean(Bus.class); 
     Map<String,Object> origBusPropMap = bus.getProperties(); 

     for(Map.Entry<String,Object> busPropEntry : origBusPropMap.entrySet()) { 
      if(busPropEntry.getKey().startsWith("bus.providers.set.")) { 
       origBusPropMap.remove(busPropEntry.getKey()); 
      } 
     } 
    } 
} 

de configuration Spring

<bean id="purgeFtryHashcodeInterceptor" class="com.mycompany.ws.interceptor.PurgeFactoryHashcodeInterceptor" /> 
 
    
 
<cxf:bus> 
 
     <cxf:properties> 
 
      <entry key="org.apache.cxf.jaxrs.bus.providers"> 
 
       <list> 
 
        <ref bean="throwableExceptionMapper" /> 
 
        <ref bean="customFilter1" /> 
 
       </list> 
 
      </entry> 
 
     </cxf:properties> 
 
     <cxf:outInterceptors> 
 
      <ref bean="purgeFtryHashcodeInterceptor" /> 
 
     </cxf:outInterceptors> 
 
</cxf:bus>

+0

Ne pas oublier de voter up, si vous aviez rencontré le même problème. –