Fast work, Azeez! Nice. Only comment - shouldn't the resolution be "fixed" instead of "invalid"?
--G On 6/22/2010 2:55 PM, Afkham Azeez (JIRA) wrote: > > [ > https://issues.apache.org/jira/browse/AXIS2-4749?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel > ] > > Afkham Azeez resolved AXIS2-4749. > --------------------------------- > > Assignee: Afkham Azeez > Resolution: Invalid > > Fixed in the trunk. Revision: 956974 > >> Tribe's AtMostOnceInterceptor could lead to OutOfMemory under heavy load and >> big messages. >> ------------------------------------------------------------------------------------------ >> >> Key: AXIS2-4749 >> URL: https://issues.apache.org/jira/browse/AXIS2-4749 >> Project: Axis2 >> Issue Type: Bug >> Affects Versions: 1.6 >> Environment: Linux 64 bit, JDK 1.6, WSO2 Carbon 2.0.3 >> Reporter: Stefano Bruna >> Assignee: Afkham Azeez >> >> Wa are stressing the WSO2 ESB with some cache mediator enabled. Messages are >> echanged by tribes through the cluster's nodes. Under heavy load and with >> some big xml messages (1 mb per message) the local variable >> Map<ChannelMessage, Long> receivedMessages is growing continuously leading >> to a potential Out of Memory if the cleaning thread that runs every 5 >> minutes is not fast enough to free up memory. >> See: >> http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/clustering/src/org/apache/axis2/clustering/tribes/AtMostOnceInterceptor.java?view=markup >> This is because when an object is passed to a HashMap as a key internally >> the original object is kept. The Hasmap is using a private class Entry that >> has the hash, the orginal object used to create the hash, and the value >> that, in this usage case, is a long. >> Somewhere inside HashMap.java >> // private variables >> final Object key; >> Object value; >> Entry next; >> final int hash; >> // constructor >> Entry(int i, Object obj, Object obj1, Entry entry) >> { >> value = obj1; <==== value, ok >> next = entry; <===== entry with the same hash >> key = obj; <======= orginal object, needed for the equals use in >> case of same hash >> hash = i; <======== key, ok >> } >> So if the AtMostOnceInterceptor manages for example 50 msg/sec and a message >> is 1 mb we could have within 5 minutes a memory usage for the >> messageReceived object of 6 GB. >> A simple solution, if we dont'to accept all this as something by desing, >> could be to pass to the HashMap the already calculated hash of the object >> (that is also the same method that is called internally int i = >> hash(obj.hashCode());) to not give the opportunity to the HashMap to keep >> the actual object used to produce the key. >> ..... >> // map >> private static final Map<Integer, Long> receivedMessagesHashCodes = >> new HashMap<Integer, Long>(); >> ..... >> Integer hashCode = new Integer(msg.hashCode()); >> >> if (receivedMessagesHashCodes.get(hashCode) == null) { // If it is a new >> message, keep track of it >> receivedMessagesHashCodes.put(hashCode, System.currentTimeMillis()); >> super.messageReceived(msg); >> } else { // If it is a duplicate message, discard it. i.e. dont call >> super.messageReceived >> log.info("Duplicate message received from " + >> TribesUtil.getName(msg.getAddress())); >> } >> etc... >> but maybe is not strong enough in the case tow messages have the same hash. >> A FIFO queue with a limited capacity ? > --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
