Liferay 6.2迁移中的内存泄漏

时间:2014-07-29 09:25:51

标签: java memory-leaks liferay liferay-6

我已从Liferay 6.1.1-ce-ga2迁移了Liferay 6.2-CE-GA2服务器。

我在自定义挂钩和主题中进行了一些更改,以便添加到新版本中。

在语言环境中,我从未遇到内存问题,也没有6.1版本的问题,但一旦投入生产,服务器将在几个小时内耗尽内存。

我尝试调整堆参数并增加服务器内存(从2GB到3GB)但似乎堆缓慢但不停止,直到我得到OutOfMemory: Java heap space或者,如果我给予更大的限制堆,系统耗尽内存。

我有一天学习catalina.out,试图最小化警告和错误,这是我在关机重启过程中看到的唯一有趣的事情(我替换了日志上的所有域名) :

[on shutdown]
WARN: The method class org.apache.commons.logging.impl.SLF4JLogFactory#release() was invoked.
WARN: Please see http://www.slf4j.org/codes.html#release for an explanation.

[...]

28-xul-2014 16:53:51 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [] appears to have started a thread named [org.python.google.common.base.internal.Finalizer] but has failed to stop it. This is very likely to create a memory leak.
28-xul-2014 16:53:51 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [] appears to have started a thread named [Thread-26] but has failed to stop it. This is very likely to create a memory leak.
28-xul-2014 16:53:51 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [] appears to have started a thread named [Thread-27] but has failed to stop it. This is very likely to create a memory leak.

[...]

16:55:40,517 ERROR [liferay/hot_deploy-1][JDBCExceptionReporter:82] Batch entry 0 insert into CalendarBooking (uuid_, groupId, companyId, userId, userName, createDate, modifiedDate, resourceBlockId, calendarId, calendarResourceId, parentCalendarBookingId, title, description, location, startTime, endTime, allDay, recurrence, firstReminder, firstReminderType, secondReminder, secondReminderType, status, statusByUserId, statusByUserName, statusDate, calendarBookingId) values ('985aac08-6457-484c-becb-2c4964805158', '10545', '10154', '10196', 'Carlos Ces', '2012-06-06 06:26:41.431000 +01:00:00', '2012-06-06 06:26:41.431000 +01:00:00', '0', '550617', '550571', '565201', 'Master Class de improvisación e tango contemporáneo con Jorge Retamoza', '<p>_    <a href="http://www.rrrrrr.es/cultura/-/blogs/master-class-de-improvisacion-e-tango-contemporaneo-con-jorge-retamoza">Master Class con Jorge Retamoza. </a></p>_<p>_    <a href="http://www.rrrrrr.es/cultura/-/blogs/master-class-de-improvisacion-e-tango-contemporaneo-con-jorge-retamoza">Organiza: Escola de Música de rrrrrr. Colabora: Concello de rrrrrr.</a></p>', 'Auditorio de rrrrrr', '1339246800000', '1339257600000', '0', '', '900000', 'email', '300000', 'email', '0', '10196', 'Carlos Ces', '2012-06-06 06:26:41.431000 +01:00:00', '565201') was aborted.  Call getNextException to see the cause. [Sanitized]
16:55:40,518 ERROR [liferay/hot_deploy-1][JDBCExceptionReporter:82] ERROR: duplicate key value violates unique constraint "ix_f4c61797"
16:55:40,536 ERROR [liferay/hot_deploy-1][SerialDestination:68] Unable to process message {destinationName=liferay/hot_deploy, response=null, responseDestinationName=null, responseId=null, payload=null, values={command=deploy, companyId=0, servletContextName=calendar-portlet}}
com.liferay.portal.kernel.messaging.MessageListenerException: com.liferay.portal.kernel.dao.orm.ORMException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at com.liferay.portal.kernel.messaging.BaseMessageListener.receive(BaseMessageListener.java:32)
    at com.liferay.portal.kernel.messaging.InvokerMessageListener.receive(InvokerMessageListener.java:72)
    at com.liferay.portal.kernel.messaging.SerialDestination$1.run(SerialDestination.java:65)
    at com.liferay.portal.kernel.concurrent.ThreadPoolExecutor$WorkerTask._runTask(ThreadPoolExecutor.java:682)
    at com.liferay.portal.kernel.concurrent.ThreadPoolExecutor$WorkerTask.run(ThreadPoolExecutor.java:593)
    at java.lang.Thread.run(Thread.java:636)
Caused by: com.liferay.portal.kernel.dao.orm.ORMException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    [...]
    ... 5 more
Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    [...]
    ... 62 more
Caused by: java.sql.BatchUpdateException: Batch entry 0 insert into CalendarBooking (uuid_, groupId, companyId, userId, userName, createDate, modifiedDate, resourceBlockId, calendarId, calendarResourceId, parentCalendarBookingId, title, description, location, startTime, endTime, allDay, recurrence, firstReminder, firstReminderType, secondReminder, secondReminderType, status, statusByUserId, statusByUserName, statusDate, calendarBookingId) values ('985aac08-6457-484c-becb-2c4964805158', '10545', '10154', '10196', 'Carlos Ces', '2012-06-06 06:26:41.431000 +01:00:00', '2012-06-06 06:26:41.431000 +01:00:00', '0', '550617', '550571', '565201', 'Master Class de improvisación e tango contemporáneo con Jorge Retamoza', '<p>_  <a href="http://www.rrrrrr.es/cultura/-/blogs/master-class-de-improvisacion-e-tango-contemporaneo-con-jorge-retamoza">Master Class con Jorge Retamoza. </a></p>_<p>_    <a href="http://www.rrrrrr.es/cultura/-/blogs/master-class-de-improvisacion-e-tango-contemporaneo-con-jorge-retamoza">Organiza: Escola de Música de rrrrrr. Colabora: Concello de rrrrrr.</a></p>', 'Auditorio de rrrrrr', '1339246800000', '1339257600000', '0', '', '900000', 'email', '300000', 'email', '0', '10196', 'Carlos Ces', '2012-06-06 06:26:41.431000 +01:00:00', '565201') was aborted.  Call getNextException to see the cause. [Sanitized]
    at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2621)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1837)
    [...]
    ... 68 more

然后服务器正常运行5个小时,每隔几分钟发出一些备用警告:

23:39:09,275 WARN  [ajp-apr-8009-exec-20][SecurityPortletContainerWrapper:623] Reject process action for http://www.rrrrrr.com/rrrrrr25n/notadeprensa on 56_INSTANCE_rk7ADlb9Ui2w
23:43:51,234 WARN  [ajp-apr-8009-exec-19][SecurityPortletContainerWrapper:623] Reject process action for http://www.rrrrrr.org/feiron/normas on 56_INSTANCE_jh6ewEPuvvjb
23:46:59,568 WARN  [ajp-apr-8009-exec-5][SecurityPortletContainerWrapper:623] Reject process action for http://www.rrrrrr.es/recursos-servizossociais on 56_INSTANCE_4eX2GzETiAQb
23:55:51,177 WARN  [ajp-apr-8009-exec-5][SecurityPortletContainerWrapper:623] Reject process action for http://www.rrrrrr.es/cans on 56_INSTANCE_4eX2GzETiAQb
00:00:13,713 WARN  [ajp-apr-8009-exec-24][SecurityPortletContainerWrapper:623] Reject process action for http://www.rrrrrr.es/rexistro on 56_INSTANCE_4eX2GzETiAQb
00:00:25,822 WARN  [ajp-apr-8009-exec-24][SecurityPortletContainerWrapper:623] Reject process action for http://www.rrrrrr.es/plenos on 110_INSTANCE_acNEFnslrX8c

然后记忆问题就开始了。我在日志上发布了第一个错误:

Exception in thread "http-apr-8080-exec-4" java.lang.OutOfMemoryError: Java heap space
01:00:01,223 ERROR [MemoryQuartzSchedulerEngineInstance_Worker-3][SimpleThreadPool:120] Error while executing the Runnable: 
java.lang.OutOfMemoryError: Java heap space
Exception in thread "fileinstall-/home/rrrrrr/liferay-portal-6.2-ce-ga2/data/osgi/modules" Exception in thread "ajp-apr-8009-AsyncTimeout" Exception in thread "ajp-apr-8009-exec-21"   at java.util.LinkedHashMap.createEntry(LinkedHashMap.java:441)
    at java.util.LinkedHashMap.addEntry(LinkedHashMap.java:423)
    at java.util.HashMap.put(HashMap.java:402)
Exception in thread "ajp-apr-8009-exec-24"  at sun.util.resources.OpenListResourceBundle.loadLookup(OpenListResourceBundle.java:134)
Exception in thread "MemoryQuartzSchedulerEngineInstance_QuartzSchedulerThread" Exception in thread "ContainerBackgroundProcessor[StandardEngine[Catalina]]"    at sun.util.resources.OpenListResourceBundle.loadLookupTablesIfNecessary(OpenListResourceBundle.java:113)
Exception in thread "ajp-apr-8009-exec-35" Exception in thread "ajp-apr-8009-exec-36" Exception in thread "ajp-apr-8009-exec-29" Exception in thread "ajp-apr-8009-exec-37"     at sun.util.resources.OpenListResourceBundle.handleGetKeys(OpenListResourceBundle.java:91)
    at sun.util.LocaleServiceProviderPool.getLocalizedObjectImpl(LocaleServiceProviderPool.java:353)
Exception in thread "ajp-apr-8009-exec-33" Exception in thread "ajp-apr-8009-exec-34" Exception in thread "ajp-apr-8009-exec-30"    at sun.util.LocaleServiceProviderPool.getLocalizedObject(LocaleServiceProviderPool.java:284)
Exception in thread "ajp-apr-8009-exec-28" Exception in thread "ajp-apr-8009-exec-31" Exception in thread "http-apr-8080-AsyncTimeout" Exception in thread "http-apr-8080-exec-5" Exception in thread "http-apr-8080-exec-2" Exception in thread "liferay/scheduler_dispatch-3" Exception in thread "ajp-apr-8009-exec-41"  at sun.util.TimeZoneNameUtility.retrieveDisplayNames(TimeZoneNameUtility.java:111)
    at sun.util.TimeZoneNameUtility.retrieveDisplayNames(TimeZoneNameUtility.java:99)
    at java.util.TimeZone.getDisplayNames(TimeZone.java:418)
    at java.util.TimeZone.getDisplayName(TimeZone.java:369)
    at java.text.SimpleDateFormat.subFormat(SimpleDateFormat.java:1110)
    at java.text.SimpleDateFormat.format(SimpleDateFormat.java:899)
    at java.text.SimpleDateFormat.format(SimpleDateFormat.java:869)
    at org.apache.tomcat.util.http.ServerCookie.appendCookieValue(ServerCookie.java:254)
    at org.apache.catalina.connector.Response.generateCookieString(Response.java:1032)
    at org.apache.catalina.connector.Response.addCookie(Response.java:974)
    at org.apache.catalina.connector.ResponseFacade.addCookie(ResponseFacade.java:381)
    at javax.servlet.http.HttpServletResponseWrapper.addCookie(HttpServletResponseWrapper.java:58)
    at com.liferay.portal.kernel.servlet.HttpOnlyCookieServletResponse.addCookie(HttpOnlyCookieServletResponse.java:62)
    at javax.servlet.http.HttpServletResponseWrapper.addCookie(HttpServletResponseWrapper.java:58)
    at javax.servlet.http.HttpServletResponseWrapper.addCookie(HttpServletResponseWrapper.java:58)
    at javax.servlet.http.HttpServletResponseWrapper.addCookie(HttpServletResponseWrapper.java:58)
    at com.liferay.portal.kernel.servlet.MetaInfoCacheServletResponse.addCookie(MetaInfoCacheServletResponse.java:128)
    at javax.servlet.http.HttpServletResponseWrapper.addCookie(HttpServletResponseWrapper.java:58)
    at com.liferay.portal.kernel.servlet.MetaInfoCacheServletResponse.addCookie(MetaInfoCacheServletResponse.java:128)
01:02:56,362 ERROR [PersistedQuartzSchedulerEngineInstance_QuartzSchedulerThread][ErrorLogger:120] An error occurred while scanning for the next triggers to fire.
org.quartz.JobPersistenceException: Failed to obtain DB connection from data source 'ds': java.lang.OutOfMemoryError: Java heap space [See nested exception: java.lang.OutOfMemoryError: Java heap space]
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.getConnection(JobStoreSupport.java:771)
    at org.quartz.impl.jdbcjobstore.JobStoreTX.getNonManagedTXConnection(JobStoreTX.java:71)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3808)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTriggers(JobStoreSupport.java:2751)
    at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:264)
Caused by: java.lang.OutOfMemoryError: Java heap space
    at javax.servlet.http.HttpServletResponseWrapper.addCookie(HttpServletResponseWrapper.java:58)
    at com.liferay.portal.kernel.servlet.MetaInfoCacheServletResponse.addCookie(MetaInfoCacheServletResponse.java:128)
    at com.liferay.portal.kernel.util.CookieKeys.addCookie(CookieKeys.java:99)
    at com.liferay.portal.kernel.util.CookieKeys.addCookie(CookieKeys.java:63)
    at com.liferay.portal.language.LanguageImpl.updateCookie(LanguageImpl.java:751)
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
01:03:00,917 ERROR [QuartzScheduler_PersistedQuartzSchedulerEngineInstance-NON_CLUSTERED_MisfireHandler][PortalJobStore:120] MisfireHandler: Error handling misfires: Unexpected runtime exception: Index: 0, Size: 0
org.quartz.JobPersistenceException: Unexpected runtime exception: Index: 0, Size: 0 [See nested exception: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0]
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.doRecoverMisfires(JobStoreSupport.java:3200)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport$MisfireHandler.manage(JobStoreSupport.java:3947)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport$MisfireHandler.run(JobStoreSupport.java:3968)
Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.ArrayList.rangeCheck(ArrayList.java:571)
    at java.util.ArrayList.get(ArrayList.java:349)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1689)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:512)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:273)
    at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.countMisfiredTriggersInState(StdJDBCDelegate.java:416)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.doRecoverMisfires(JobStoreSupport.java:3176)
    ... 2 more
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
Exception in thread "fileinstall-/home/rrrrrr/liferay-portal-6.2-ce-ga2/data/osgi/portal" java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space

我现在有一些自定义主题和钩子。我不知道它们的任何地方都有内存泄漏,但我找不到它。

首先,我为博客提供了自定义Application Display Template

<div class="cr-blog container-fluid">
 #foreach ($entry in $entries)
 <div class="entry-content">
  #set ($viewUrl = $currentURL.replaceFirst("\?.*$","") + "/-/blogs/" + $entry.getUrlTitle())
  #set($img_ini=$entry.content.indexOf("<img"))

  #if ($img_ini >= 0)
   #set($img_end=$entry.content.indexOf(">",$img_ini) + 1)
   #set($first_img_tag= $entry.content.substring($img_ini, $img_end))

   #set($first_img_url=$first_img_tag.replaceFirst("<img.*src=\"",""))
   #set($first_img_url=$first_img_url.replaceFirst("\".*","")) 
  #end

  <div class="entry-extract">

   #if ($img_ini >= 0)
   <div class="extract-thumbnail">
     <a href="$viewUrl">
      <img src="$escapeTool.html($first_img_url)" />
     </a>
   </div>
   #end

   <div class="extract-title">
    <a href="$viewUrl"><span>$entry.title</span></a>
   </div>


   <div class="extract-content">
    <a href="$viewUrl">
     <span class="extract-date">$dateFormats.getSimpleDateFormat("dd MMMMM yyyy HH:mm", $locale).format($entry.displayDate)</span>
      #set($plain_content = $entry.content.replaceAll("</?[^>]+/?>", ""))
      #set($res_length = 240)
      #if ($res_length > $plain_content.length())
       #set($res_length = $plain_content.length())
      #end
      <p>
       $plain_content.substring(0,$res_length) ...
      </p>
    </a>
   </div>
  </div>
 </div>
 #end
</div>

自定义钩子Blogshome会覆盖blogs_aggregator中的一些jsps。

view_entries.jspf

<c:choose>
    <c:when test="<%= results.isEmpty() %>">
        <liferay-ui:message key="there-are-no-blogs" />

        <br /><br />
    </c:when>
    <c:otherwise>

        <%

        if (displayStyle.startsWith("extract-side-events")) {

            List<BlogsEntry> eventsColumn = new ArrayList<BlogsEntry>();
            List<BlogsEntry> mainColumn = new ArrayList<BlogsEntry>();

            for (int i=0; i< results.size(); i++) {
                BlogsEntry entry = (BlogsEntry) results.get(i);

                if (entry.getDisplayDate().after(new Date())) {
                    searchContainer.setTotal(searchContainer.getTotal() - 1);
                    continue;
                }



                boolean isEvent = ((Boolean) entry.getExpandoBridge().getAttribute("evento"));

                if (isEvent) eventsColumn.add(entry);
                mainColumn.add(entry); /* change: add ALL to mainColumn; events are duplicated on side */
            }

                        /* reorder eventsColumn */

                        TreeMap<Date, BlogsEntry> next= new TreeMap<Date, BlogsEntry>();
            List<BlogsEntry> toRemove = new ArrayList<BlogsEntry>();

                for (BlogsEntry entry: eventsColumn) {
                                Date ini = (Date) entry.getExpandoBridge().getAttribute("evento-inicio");
                                Date end = (Date) entry.getExpandoBridge().getAttribute("evento-remate");
                                Date now = new Date();

                                if (ini.before(now) && (end.after(now))) {
                    next.put(end, entry);
                    /* mainColumn.remove(entry); */
                } else if (end.before(now)) {
                    toRemove.add(entry);
                } else {
                    next.put(ini, entry);
                    /* mainColumn.remove(entry); */
                }
                        }
            eventsColumn.removeAll(toRemove);

            /* third rearrangement: current & next are visible; past are pushed to mainColumn */
            /* current ordered by end; next ordered by ini */

                        ArrayList<BlogsEntry> lNext = new ArrayList<BlogsEntry>(next.values());

                        %> <div class="home-events">
                <div class="events-showdown" id="events-showdown">


            <%
                if (!lNext.isEmpty()) { 

                                for (BlogsEntry entry: lNext) {
                                        %>  
                            <div class="carousel-item">
                                                <%@ include file="/html/portlet/blogs_aggregator/view_entry_extract.jspf" %>
                            </div>
                                        <%                                    
                                }
                }
            %>

                </div>
                <script>
                    YUI().use('aui-carousel', function(Y) { new Y.Carousel( {contentBox: '#events-showdown',
                        height: 320, width: 600, intervalTime: 5 }).render(); });
                </script>
<%--
                <div class="home-events-nav">
                    <button type="button" class="btn btn-default btn-large"
                    onclick="document.getElementById('events-showdown').style.right =50">
                        <span class="glyphicon glyphicon-chevron-right"></span>
                    </button>
                </div>
--%>
            </div> <%


                        %> <div class="home-blogs container-fluid" > <%                    
                        for (BlogsEntry entry: mainColumn) {
                                    %>  
                                        <%@ include file="/html/portlet/blogs_aggregator/view_entry_extract.jspf" %>
                                    <%
                        }
                        %> </div> <%


                /* original blogs styles */        
                } else {

            for (int i = 0; i < results.size(); i++) {
                BlogsEntry entry = (BlogsEntry)results.get(i);

                if (entry.getDisplayDate().after(new Date())) {
                    searchContainer.setTotal(searchContainer.getTotal() - 1);
                    continue;
                }
            %>  
                <%@ include file="/html/portlet/blogs_aggregator/view_entry_content.jspf" %>
            <%
            }
        }
        %>

    </c:otherwise>
</c:choose>

<c:if test="<%= enableRssSubscription %>">

    <%
    StringBundler rssURLParams = new StringBundler();

    if (selectionMethod.equals("users")) {
        if (organizationId > 0) {
            rssURLParams.append("&organizationId=");
            rssURLParams.append(organizationId);
        }
        else {
            rssURLParams.append("&companyId=");
            rssURLParams.append(company.getCompanyId());
        }
    }
    else {
        rssURLParams.append("&groupId=");
        rssURLParams.append(themeDisplay.getScopeGroupId());
    }
    %>

    <span class="button">
        <liferay-ui:icon
            image="rss"
            label="<%= true %>"
            method="get"
            target="_blank"
            url='<%= themeDisplay.getPathMain() + "/blogs_aggregator/rss?p_l_id=" + plid + rssURLParams %>'
        />
    </span>
</c:if>

<c:if test="<%= !results.isEmpty() %>">
    <div class="search-container">
        <liferay-ui:search-paginator searchContainer="<%= searchContainer %>" />
    </div>
</c:if>

view_entry_extract.jspf

<c:if test="<%= BlogsEntryPermission.contains(permissionChecker, entry, ActionKeys.VIEW) %>">
    <div class="entry-content">

        <%
        PortletURL showBlogEntryURL = renderResponse.createRenderURL();

        showBlogEntryURL.setParameter("struts_action", "/blogs_aggregator/view_entry");
        showBlogEntryURL.setParameter("entryId", String.valueOf(entry.getEntryId()));

        StringBundler sb = new StringBundler(8);

        StringBundler ab = new StringBundler(8);
        ab.append(themeDisplay.getURLPortal());
        ab.append(GroupLocalServiceUtil.getGroup(entry.getGroupId()).getFriendlyURL());
        ab.append("/-/blogs/");
        ab.append(entry.getUrlTitle());

        String viewEntryURL = ab.toString();

        sb.append("&showAllEntries=1");

        String viewAllEntriesURL = sb.toString();

        User user2 = UserLocalServiceUtil.getUserById(entry.getUserId());
        %>

        <div class="entry-header">

            <c:if test='<%= (Boolean) entry.getExpandoBridge().getAttribute("evento")%>'>
                <div class="event-schedule">

        <%

                        Calendar iniDate = com.liferay.portal.kernel.util.CalendarFactoryUtil.getCalendar(timeZone);
                        Calendar endDate = com.liferay.portal.kernel.util.CalendarFactoryUtil.getCalendar(timeZone);
                        iniDate.setTime(((Date) entry.getExpandoBridge().getAttribute("evento-inicio")));
                        endDate.setTime(((Date) entry.getExpandoBridge().getAttribute("evento-remate")));
                                                                            boolean sameDay = false;

                        if ((iniDate.get(Calendar.DAY_OF_YEAR) == endDate.get(Calendar.DAY_OF_YEAR))
                         && (iniDate.get(Calendar.YEAR) == endDate.get(Calendar.YEAR))) 
                sameDay = true;

            String diaDaSemana = (new SimpleDateFormat("EEEE", locale)).format(iniDate.getTime());
            String numeroDeDia = (new SimpleDateFormat("d", locale)).format(iniDate.getTime());
            String mes = (new SimpleDateFormat("MMMM", locale)).format(iniDate.getTime());
//          String hora = (new SimpleDateFormat("HH:mm", locale)).format(iniDate.getTime()) + "h"; 
            String hora = (iniDate.get(Calendar.HOUR_OF_DAY) +  new SimpleDateFormat(":mm", locale).format(iniDate.getTime()) + "h");

            String numeroDeDiaFin = StringPool.BLANK;
            String mesFin = StringPool.BLANK;
            if (!sameDay) {
                numeroDeDiaFin = (new SimpleDateFormat("d", locale)).format(endDate.getTime());
                mesFin = (new SimpleDateFormat("MMMM", locale)).format(endDate.getTime());
            }

        %>

        <%
            if (sameDay) {
        %>
            <div class='event-date'>
                <%= numeroDeDia %>
            </div>
            <div class='event-data'>
                <div class="event-month"><%= mes  %></div>
                <div class="event-day"><%= diaDaSemana  %></div>
                <div class="event-time"><%= hora  %></div>
            </div>

        <%
            } else {
        %>
            <div class='event-date'>
                <%= numeroDeDia %>
            </div>
            <div class='event-data'>
                <div class="event-month"><%= mes  %></div>
                <div class="event-day"><%= diaDaSemana  %></div>
                <div class="event-time"><liferay-ui:message key="rrrrrr.events.until" /> <%= numeroDeDiaFin %> 
                            <liferay-ui:message key="rrrrrr.events.of" /> <%= mesFin  %></div>
            </div>

        <%

            }
        %>          

                </div>
            </c:if>


        </div>

        <div class="entry-extract">

            <%

            String resumeText = StringPool.BLANK;
            String resumeImage = StringPool.BLANK;
            int extLength = 240;

            if (entry.isSmallImage()) {
                if (Validator.isNotNull(entry.getSmallImageURL()))
                    resumeImage = entry.getSmallImageURL();
                else
                    resumeImage = themeDisplay.getPathImage() + "/journal/article?img_id=" + entry.getSmallImageId() + "&t=" + WebServerServletTokenUtil.getToken(entry.getSmallImageId()) ;
                resumeImage.trim();
            }

            /* if no small image, extract first */
            if ((resumeImage == null) || (resumeImage.isEmpty())) {

                java.util.regex.Pattern p = java.util.regex.Pattern.compile("src=['\"]([^'\"]+)['\"]");
                java.util.regex.Matcher m = p.matcher(entry.getContent());
                if (m.find())
                    resumeImage = m.group().substring(5, m.group().length() -1);
            }

            resumeText = HtmlUtil.stripHtml(entry.getDescription());
            resumeText.trim();

            /* if no resume description, extract text */
            if ((resumeText == null) || (resumeText.isEmpty())) {
                resumeText = HtmlUtil.escape(StringUtil.shorten(HtmlUtil.extractText(entry.getContent()), extLength));
            }

            %>

            <div class="extract-thumbnail">
                <a href="<%= viewEntryURL %>"  style="background-image: url('<%= HtmlUtil.escape(resumeImage) %>')">
                    <img class="asset-small-image" src="<%= HtmlUtil.escape(resumeImage) %>"/> 
                </a>
            </div>

            <div class="extract-title">
                <a href="<%= viewEntryURL %>"><%= HtmlUtil.escape(entry.getTitle()) %></a>
            </div>

            <div class="extract-content">
                <a href="<%= viewEntryURL %>">
                    <span class="extract-scope"><%= GroupLocalServiceUtil.getGroup(entry.getGroupId()).getDescriptiveName() %></span> 
                    <span class="extract-date"><%= dateFormatDateTime.format(entry.getDisplayDate()) %></span> 
                    <span><%= " " + resumeText %></span>
                </a>
            </div>

        </div>

    </div>

我无法猜到那里有任何内存泄漏,但必须有!我花了几个星期试图找到一个错误(停用钩子以查看错误是否仍然存在),但无法找到线索。

有人在我的代码中看到了一些有潜在危险的东西吗?我可以通过其他方式跟踪Java内存使用情况以获取泄漏吗?

2 个答案:

答案 0 :(得分:0)

这真是一个混乱的代码...... 首先不要使用scriplets使用servlet。
不要丢弃那些数量的代码来识别你的问题,然后缩小你的问题,以便我们回答它
你可以在eclipse中利用MAT进行堆栈转储,并分析哪些对象占用了大量内存,因此导致内存泄漏的原因。
为什么要将JSTL与scriplet混合使用? JSTL设计用于servlet。

您将业务逻辑与表示层混淆,这就是强烈不建议使用scriplet的原因。当你把它改成scriplet然后我就能给你一些答案时,你的代码不易读回来。

答案 1 :(得分:0)

您描述的症状与内存泄漏有关。如果你怀疑一个,请尝试Plumbr找到原因并解决它。如果您只是需要有关您所面临的java.lang.OutOfMemoryError: Java heap space的更多信息,请参阅有关错误,可能原因和解决方案的信息性帖子。