2017-02-21 2 views
1

Ich habe ein großes Problem mit Speicherlecks in meiner Web-App. Die Anwendung hat nach ungefähr 7 Stunden keinen Speicherplatz mehr, wenn sie von wenigen Personen verwendet wird. DieseWie Speicherlecks in Webapp jagen?

ist, wie meine app funktioniert:

  • Benutzer landet auf Login-Seite, anmeldet, auf succesfull Login Benutzerobjekt POJO wird Sitzungs Karte wie folgt hinzugefügt:. FacesContext.getCurrentInstance() getExternalContext() .getSessionMap(). put ("Benutzer", Benutzer);
  • AuthFilter überprüft bei jeder nachfolgenden Seitenanforderung, ob sich ein "Benutzer" -Objekt in der Sitzungszuordnung befindet und ermöglicht weiteren Zugriff.
  • Ich habe SessionScoped Bean (LoggedUserBean), die Benutzerinformationen enthält (zusammen mit Berechtigungen, bei der Anmeldung initialisiert), weil es sehr häufig zugegriffen wird. LoggedUserBean wird in die meisten Beans eingefügt und es wird auch direkt von XHTML-Seiten zugegriffen.
  • Es gibt auch einige andere SessionScoped-Beans, die ihren Status beibehalten sollten. Die meisten Beans haben DAO-Objekte (@named, default @ dependent) injiziert. Sehr wenige Beans und alle DAO-Objekte haben das DatabaseConnection-Objekt (@Named mit der im Konstruktor erstellten Datenquelle wie folgt eingefügt: dataSource = (DataSource) new InitialContext().lookup("java:comp/env/" + "jdbc/MyResName");).
  • gibt es nur wenige (@Named) Validatoren für Primefaces Dialoge, die dynamisch erstellte Komponente Bäume validieren:

<h:inputHidden value="true"> <f:validator binding="#{someValidator}"/> </h:inputHidden>

und Umsetzung ist in etwa so:

@Named 
public class SomeValidator extends ValidatorCommon implements Validator { 

    private final static Logger LOGGER = Logger.getLogger(SomeValidator.class); 

    @Override 
    public void validate(FacesContext fc, UIComponent uic, Object o) throws ValidatorException {...} 
{...} 

Das ist mein Kontext .xml:

<Resource auth="Container" 
      driverClassName="org.sqlite.JDBC" 
      maxTotal="1" 
      maxIdle="1" 
      minIdle="1" 
      maxWaitMillis="5000" 
      initialSize="1" 
      name="jdbc/MyResName" 
      type="javax.sql.DataSource" 
      removeAbandonedOnBorrow="true" 
      removeAbandonedTimeout="5" 
      logAbandoned="true" 
      validationQuery="SELECT 1" 
      url="jdbc:sqlite:path/to/db/db.db"> 
</Resource> 

Ich habe mit VisualVM Heapdump erstellt und MAT zeigt dieses Leck vermuten (https://i.imgur.com/wGsnyt5.png): http://i.imgur.com/wGsnyt5.png

Soweit ich verstehe, ist RequestScoped bean jedes Mal erstellt es angefordert wird/zugegriffen, während SessionScoped für bestimmte aus dem Behälter wiedergewonnen Sitzung (oder wird erstellt, wenn es nicht existiert), also selbst wenn es Querverweise zwischen meinen Beans gibt, sollte dies alles gut funktionieren.

Hier brauche ich eigentlich Hilfe: Wie analysiert man, wo diese Lecks herkommen? Es gibt definitiv etwas, das keine Freigabe von Erinnerungen erlaubt, aber wie kann ich es finden?

Ich benutze Primefaces 6.0, Apache Tomcat (TomEE)/8.5.3 (7.0.1), JDK 1.7.0_80-b15, Mojarra 2.2.6, sqlite-jdbc 3.14.2.1.

Wenn zusätzliche Dateien erforderlich sind, lassen Sie es mich wissen und ich werde diesen Beitrag bearbeiten, um sie hinzuzufügen.

Web.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns="http://java.sun.com/xml/ns/javaee" 
     xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
     id="WebApp_ID" version="3.0"> 

    <context-param> 
     <param-name>javax.faces.PROJECT_STAGE</param-name> 
     <param-value>Development</param-value> 
    </context-param> 

    <context-param> 
     <param-name>javax.faces.STATE_SAVING_METHOD</param-name> 
     <param-value>client</param-value> 
    </context-param> 

    <context-param> 
     <param-name>primefaces.FONT_AWESOME</param-name> 
     <param-value>true</param-value> 
    </context-param> 

    <resource-env-ref> 
     <resource-env-ref-name>jdbc/MyResName</resource-env-ref-name> 
     <resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type> 
    </resource-env-ref> 

    <!-- Welcome page --> 
    <welcome-file-list> 
     <welcome-file>pages/pub/login.xhtml</welcome-file> 
    </welcome-file-list> 

    <!-- Error pages --> 
    <error-page> 
     <exception-type>javax.faces.application.ViewExpiredException</exception-type> 
     <location>/pages/pub/err/expired.xhtml</location> 
    </error-page> 

    <!-- Prevents comments in xhtml pages to be placed in final html and evaluated --> 
    <context-param> 
     <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name> 
     <param-value>true</param-value> 
    </context-param> 

    <!-- JSF mapping --> 
    <servlet> 
     <servlet-name>Faces Servlet</servlet-name> 
     <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>Faces Servlet</servlet-name> 
     <url-pattern>*.xhtml</url-pattern> 
    </servlet-mapping> 

    <!-- Primefaces theme --> 
    <context-param> 
     <param-name>primefaces.THEME</param-name> 
     <param-value>cupertino</param-value> 
    </context-param> 

    <session-config> 
     <session-timeout>120</session-timeout> 
    </session-config> 

    <filter> 
     <filter-name>forceUTF8CharSet</filter-name> 
     <filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class> 
     <init-param> 
     <param-name>encoding</param-name> 
     <param-value>utf-8</param-value> 
     </init-param> 
    </filter> 

    <filter-mapping> 
     <filter-name>forceUTF8CharSet</filter-name> 
     <url-pattern>*</url-pattern> 
    </filter-mapping> 

    <mime-mapping> 
     <extension>ttf</extension> 
     <mime-type>application/font-sfnt</mime-type> 
    </mime-mapping> 
    <mime-mapping> 
     <extension>woff</extension> 
     <mime-type>application/font-woff</mime-type> 
    </mime-mapping> 
    <mime-mapping> 
     <extension>woff2</extension> 
     <mime-type>application/font-woff2</mime-type> 
    </mime-mapping> 
    <mime-mapping> 
     <extension>eot</extension> 
     <mime-type>application/vnd.ms-fontobject</mime-type> 
    </mime-mapping> 
     <mime-mapping> 
     <extension>eot?#iefix</extension> 
     <mime-type>application/vnd.ms-fontobject</mime-type> 
    </mime-mapping> 
    <mime-mapping> 
     <extension>svg</extension> 
     <mime-type>image/svg+xml</mime-type> 
    </mime-mapping> 
    <mime-mapping> 
     <extension>svg#latobold</extension> 
     <mime-type>image/svg+xml</mime-type> 
    </mime-mapping> 
    <mime-mapping> 
     <extension>svg#latoblack</extension> 
     <mime-type>image/svg+xml</mime-type> 
    </mime-mapping> 
     <mime-mapping> 
     <extension>svg#latolight</extension> 
     <mime-type>image/svg+xml</mime-type> 
    </mime-mapping> 
    <mime-mapping> 
     <extension>svg#latoregular</extension> 
     <mime-type>image/svg+xml</mime-type> 
    </mime-mapping> 
    <mime-mapping> 
     <extension>svg#fontawesomeregular</extension> 
     <mime-type>image/svg+xml</mime-type> 
</mime-mapping> 
</web-app> 

Antwort

0

Ich habe es geschafft, mein Problem zu lösen.

Mein Problem war nicht in jedem meiner Bohnen, Handler, Validierer, Authentifizierungsmechanismen usw. Echt Problem war, dass ich zwei Libs in pom.xml enthalten:

<dependency> 
    <groupId>com.sun.faces</groupId> 
    <artifactId>jsf-api</artifactId> 
    <version>2.2.6</version> 
</dependency> 
<dependency> 
    <groupId>com.sun.faces</groupId> 
    <artifactId>jsf-impl</artifactId> 
    <version>2.2.6</version> 
</dependency> 

Ich weiß nicht recht, wie funktioniert TomEE verhält sich, wenn es zwei separate Implementierungen (TomEE's und höher) gibt, aber es scheint, dass etwas die Freigabe von Verweisen auf einige Ressourcen verhindert hat, was dazu geführt hat, dass WebContext immer größer wurde (es enthielt alle Objekte, die an der Anfrageverarbeitung beteiligt waren - über mehrere Seiten hinweg) . Oder ist das ein Fehler in der jsf-Implementierung?

Wenn jemand erklären könnte, was tatsächlich passiert ist, dann würde ich diese Antwort als Lösung für mein Problem akzeptieren. Bis dahin ist diese Antwort (ohne viel Nachdenken) die Lösung.

0

vielleicht starten, indem Sie einen Versuch zu TomEE 7.0.2 geben. Wenn es nicht hilft, dann versuchen Sie, WebContext Map zu debuggen, um zu prüfen, welche CDI-Beans nicht freigegeben sind, dann werden Sie wissen können, wer (tomee, tomcat, primefaces, andere) dafür verantwortlich ist und prüfen, ob Sie es beheben können.

+0

Ich werde zuerst mit neueren TomEE versuchen. Es überrascht mich auch, dass ich nicht über das Debuggen von Tomcat nachgedacht habe ... Ich werde es versuchen und werde in ~ 8h zu dir zurückkommen. – Mithras