ofbiz-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Michael Brohl (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (OFBIZ-6621) MapContext.entrySet() slows down when ByteBuffer objects are in the context
Date Sat, 19 Sep 2015 08:55:04 GMT

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

Michael Brohl updated OFBIZ-6621:
---------------------------------
    Fix Version/s: Release Branch 14.12
                   Upcoming Branch

> MapContext.entrySet() slows down when ByteBuffer objects are in the context
> ---------------------------------------------------------------------------
>
>                 Key: OFBIZ-6621
>                 URL: https://issues.apache.org/jira/browse/OFBIZ-6621
>             Project: OFBiz
>          Issue Type: Improvement
>          Components: framework
>    Affects Versions: Release Branch 14.12, Upcoming Branch
>            Reporter: Gareth Carter
>            Assignee: Michael Brohl
>            Priority: Critical
>             Fix For: Release Branch 14.12, Upcoming Branch
>
>         Attachments: MapContext-v2.patch, MapContext.patch
>
>
> When MapContext is used anywhere (eg FlexibleStringExpander) and the context contains
ByteBuffer objects (either key or value), java will slow down when calling MapContext.entrySet().
> Here is the code in ofbiz, highlighted is the line of code that I believe is the culprit
> {code:title=MapContext.java}
> public Set<Map.Entry<K, V>> entrySet() {
>     // walk the stackList and the entries for each Map and if nothing is in for the current
key, put it in
>     Set<K> resultKeySet = new HashSet<K>();
>     culprit --> Set<Map.Entry<K, V>> resultEntrySet = new ListSet<Map.Entry<K,
V>>();
>     for (Map<K, V> curMap: this.stackList) {
>         for (Map.Entry<K, V> curEntry: curMap.entrySet()) {
>             if (!resultKeySet.contains(curEntry.getKey())) {
>                 resultKeySet.add(curEntry.getKey());
>                 resultEntrySet.add(curEntry);
>             }
>         }
>     }
>     return Collections.unmodifiableSet(resultEntrySet);
> }
> {code}
> Looking at the java api for Map.Entry, the hashCode method for Map.Entry is the result
of the hashCode from both key and value. ByteBuffer hash code is dependent upon its content.
If a 2mb file is uploaded, the hashCode method
> of ByteBuffer will scan 2mb to generate the hashCode
> ByteBuffer
> http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html#hashCode()
> {quote}Because buffer hash codes are content-dependent, it is inadvisable to use buffers
as keys in hash maps or similar data structures unless it is known that their contents will
not change.{quote}
> Map.Entry
> http://docs.oracle.com/javase/7/docs/api/java/util/Map.Entry.html#hashCode()
> {quote}(e.getKey()==null   ? 0 : e.getKey().hashCode()) ^ (e.getValue()==null ? 0 : e.getValue().hashCode()){quote}
> HashSet
> http://docs.oracle.com/javase/7/docs/api/java/util/HashSet.html
> {quote}This class implements the Set interface, backed by a hash table (actually a HashMap
instance{quote}
> Example where ByteBuffer objects are created
> {code}org.ofbiz.webapp.event.ServiceEventHandler{code}
> Example stack trace
> {noformat}
> "ajp-bio-8009-exec-1894" daemon prio=10 tid=0x00007fa52c070000 nid=0x5c73 runnable [0x00007fa51151b000]
>    java.lang.Thread.State: RUNNABLE
> 	at java.nio.HeapByteBuffer.ix(HeapByteBuffer.java:131)
> 	at java.nio.HeapByteBuffer.get(HeapByteBuffer.java:139)
> 	at java.nio.ByteBuffer.hashCode(ByteBuffer.java:1083)
> 	at java.util.Objects.hashCode(Objects.java:96)
> 	at java.util.HashMap$Entry.hashCode(HashMap.java:847)
> 	at java.util.AbstractMap.hashCode(AbstractMap.java:494)
> 	at java.util.Objects.hashCode(Objects.java:96)
> 	at java.util.HashMap$Entry.hashCode(HashMap.java:847)
> 	at java.util.HashMap.hash(HashMap.java:362)
> 	at java.util.HashMap.put(HashMap.java:492)
> 	at java.util.HashSet.add(HashSet.java:217)
> 	at org.ofbiz.base.util.collections.MapContext.entrySet(MapContext.java:306)
> 	at java.util.HashMap.putAll(HashMap.java:642)
> 	at org.ofbiz.widget.model.ModelFormField$ListOptions.addOptionValues(ModelFormField.java:2716)
> 	at org.ofbiz.widget.model.ModelFormField$FieldInfoWithOptions.getAllOptionValues(ModelFormField.java:1985)
> 	at org.ofbiz.widget.renderer.macro.MacroFormRenderer.renderDropDownField(MacroFormRenderer.java:747)
> 	at org.ofbiz.widget.model.ModelFormField$DropDownField.renderFieldString(ModelFormField.java:1739)
> 	at org.ofbiz.widget.model.ModelFormField.renderFieldString(ModelFormField.java:693)
> 	at org.ofbiz.widget.renderer.FormRenderer.renderSingleFormString(FormRenderer.java:1195)
> 	at org.ofbiz.widget.renderer.FormRenderer.render(FormRenderer.java:261)
> 	at org.ofbiz.widget.model.ModelScreenWidget$Form.renderWidgetString(ModelScreenWidget.java:1052)
> 	at org.ofbiz.widget.renderer.macro.MacroScreenRenderer.renderScreenletSubWidget(MacroScreenRenderer.java:677)
> 	at org.ofbiz.widget.model.ModelScreenWidget$Screenlet.renderWidgetString(ModelScreenWidget.java:598)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$Section.renderWidgetString(ModelScreenWidget.java:280)
> 	at org.ofbiz.widget.model.ModelScreen.renderScreenString(ModelScreen.java:164)
> 	at org.ofbiz.widget.model.ScreenFactory.renderReferencedScreen(ScreenFactory.java:211)
> 	at org.ofbiz.widget.model.ModelScreenWidget$IncludeScreen.renderWidgetString(ModelScreenWidget.java:779)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$Container.renderWidgetString(ModelScreenWidget.java:459)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$Section.renderWidgetString(ModelScreenWidget.java:280)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$DecoratorSection.renderWidgetString(ModelScreenWidget.java:905)
> 	at org.ofbiz.widget.model.ModelScreenWidget$SectionsRenderer.render(ModelScreenWidget.java:127)
> 	at org.ofbiz.widget.model.ModelScreenWidget$DecoratorSectionInclude.renderWidgetString(ModelScreenWidget.java:942)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$Section.renderWidgetString(ModelScreenWidget.java:280)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$DecoratorSection.renderWidgetString(ModelScreenWidget.java:905)
> 	at org.ofbiz.widget.model.ModelScreenWidget$SectionsRenderer.render(ModelScreenWidget.java:127)
> 	at org.ofbiz.widget.model.ModelScreenWidget$DecoratorSectionInclude.renderWidgetString(ModelScreenWidget.java:942)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$DecoratorSection.renderWidgetString(ModelScreenWidget.java:905)
> 	at org.ofbiz.widget.model.ModelScreenWidget$SectionsRenderer.render(ModelScreenWidget.java:127)
> 	at org.ofbiz.widget.model.ModelScreenWidget$DecoratorSectionInclude.renderWidgetString(ModelScreenWidget.java:942)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$Container.renderWidgetString(ModelScreenWidget.java:459)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$Section.renderWidgetString(ModelScreenWidget.java:280)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$Container.renderWidgetString(ModelScreenWidget.java:459)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$Container.renderWidgetString(ModelScreenWidget.java:459)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$Section.renderWidgetString(ModelScreenWidget.java:280)
> 	at org.ofbiz.widget.model.ModelScreen.renderScreenString(ModelScreen.java:164)
> 	at org.ofbiz.widget.model.ScreenFactory.renderReferencedScreen(ScreenFactory.java:211)
> 	at org.ofbiz.widget.model.ModelScreenWidget$DecoratorScreen.renderWidgetString(ModelScreenWidget.java:859)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$Section.renderWidgetString(ModelScreenWidget.java:280)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$Section.renderWidgetString(ModelScreenWidget.java:280)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$Section.renderWidgetString(ModelScreenWidget.java:280)
> 	at org.ofbiz.widget.model.ModelScreen.renderScreenString(ModelScreen.java:164)
> 	at org.ofbiz.widget.model.ScreenFactory.renderReferencedScreen(ScreenFactory.java:211)
> 	at org.ofbiz.widget.model.ModelScreenWidget$DecoratorScreen.renderWidgetString(ModelScreenWidget.java:859)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$Section.renderWidgetString(ModelScreenWidget.java:280)
> 	at org.ofbiz.widget.model.ModelScreen.renderScreenString(ModelScreen.java:164)
> 	at org.ofbiz.widget.model.ScreenFactory.renderReferencedScreen(ScreenFactory.java:211)
> 	at org.ofbiz.widget.model.ModelScreenWidget$DecoratorScreen.renderWidgetString(ModelScreenWidget.java:859)
> 	at org.ofbiz.widget.model.ModelScreenWidget.renderSubWidgetsString(ModelScreenWidget.java:98)
> 	at org.ofbiz.widget.model.ModelScreenWidget$Section.renderWidgetString(ModelScreenWidget.java:280)
> 	at org.ofbiz.widget.model.ModelScreen.renderScreenString(ModelScreen.java:164)
> 	at org.ofbiz.widget.renderer.ScreenRenderer.render(ScreenRenderer.java:136)
> 	at org.ofbiz.widget.renderer.ScreenRenderer.render(ScreenRenderer.java:98)
> 	at org.ofbiz.widget.renderer.macro.MacroScreenViewHandler.render(MacroScreenViewHandler.java:157)
> 	at org.ofbiz.webapp.control.RequestHandler.renderView(RequestHandler.java:989)
> 	at org.ofbiz.webapp.control.RequestHandler.doRequest(RequestHandler.java:676)
> 	at org.ofbiz.webapp.control.ControlServlet.doGet(ControlServlet.java:221)
> 	at org.ofbiz.webapp.control.ControlServlet.doPost(ControlServlet.java:89)
> 	at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
> 	at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
> 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
> 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
> 	at org.ofbiz.webapp.control.ContextFilter.doFilter(ContextFilter.java:321)
> 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
> 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
> 	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
> 	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
> 	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
> 	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
> 	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
> 	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
> 	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
> 	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
> 	at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:190)
> 	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
> 	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
> 	- locked <0x00000006f95b1cf0> (a org.apache.tomcat.util.net.SocketWrapper)
> 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
> 	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
> 	at java.lang.Thread.run(Thread.java:745)
> {noformat}
>     
> The solution would be not to use HashSet but instead a simpler Set class such as a Set
backed by a List. 



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

Mime
View raw message