RFR: 7879: Automated Analysis taking very long time to produce results for Class Leak Rule and showing wrong results.
    Brice Dutheil 
    bdutheil at openjdk.org
       
    Wed Oct  5 11:03:35 UTC 2022
    
    
  
On Sat, 20 Aug 2022 18:59:14 GMT, Suchita Chaturvedi <schaturvedi at openjdk.org> wrote:
> This PR takes care of optimizing and correcting the Class leak rule results on Automated Analysis Page.
I believe some changes are still required.
core/org.openjdk.jmc.flightrecorder.rules.jdk/src/main/java/org/openjdk/jmc/flightrecorder/rules/jdk/general/ClassLeakingRule.java line 105:
> 103: 
> 104: 	public static final TypedPreference<IQuantity> MAX_TIMEOUT = new TypedPreference<>(
> 105: 			"classLeaking.calculation.timeout", //$NON-NLS-1$
Just a suggestion
Suggestion:
			"classLeakingRuke.calculation.timeout", //$NON-NLS-1$
core/org.openjdk.jmc.flightrecorder.rules.jdk/src/main/java/org/openjdk/jmc/flightrecorder/rules/jdk/util/DefaultIItemResultSet.java line 54:
> 52: import org.openjdk.jmc.common.item.IType;
> 53: import org.openjdk.jmc.common.item.ItemFilters;
> 54: import org.openjdk.jmc.flightrecorder.rules.jdk.general.ClassLeakingRule;
I don't think that desirable to make `DefaultIItemResultSet` depend on `ClassLeakingRule`, this make every rule that use that class usage of that class having the same timeout as `ClassLeakingRule` (even if _as of today_ only 2 rule use this).
I believe the code will be better to add an override like this (adapt the timeout type if necessary), and of course the constructor of `DefaultIItemResultSet`.
  public class ItemResultSetFactory {
  	public IItemResultSet createResultSet(IItemCollection items, IItemQuery query)  {
  		return new DefaultIItemResultSet(items, query);
  	}
+ 	public IItemResultSet createResultSet(IItemCollection items, IItemQuery query, LinearQuantity timeout) {
+ 		return new DefaultIItemResultSet(items, query, timeout);
+ 	}
  }
And make `ItemResultSetFactory.createResultSet(IItemCollection items, IItemQuery query)` use the default timeout. Maybe the default can be `null` to indicate there's no timeout, I think `MINUTE.quantity(-1)` could work.
-----
Rule usages
https://github.com/openjdk/jmc/blob/1696e03a1fddb9cc68d32bf21a281ef24366e552/core/org.openjdk.jmc.flightrecorder.rules.jdk/src/main/java/org/openjdk/jmc/flightrecorder/rules/jdk/general/ClassLeakingRule.java#L220
https://github.com/openjdk/jmc/blob/1696e03a1fddb9cc68d32bf21a281ef24366e552/core/org.openjdk.jmc.flightrecorder.rules.jdk/src/main/java/org/openjdk/jmc/flightrecorder/rules/jdk/latency/BiasedLockingRevocationRule.java#L256
core/org.openjdk.jmc.flightrecorder.rules.jdk/src/main/java/org/openjdk/jmc/flightrecorder/rules/jdk/util/DefaultIItemResultSet.java line 128:
> 126: 								synchronized (data) {
> 127: 									data.add(row);
> 128: 								}
In my previous [comment](https://github.com/openjdk/jmc/pull/248/files#r633606757) on #248 I was thinking more about tweaking the collection, sorry for the lack of precision back then. So something like:
- private final ArrayList<Object[]> data = new ArrayList<>();
+ private final List<Object[]> data = Collections.synchronizedList(new ArrayList<Object>());
Or if the insertion order is irrelevant one might think of a `ConcurrentLinkedQueue` instead during the calculation, and copy the elements in the array list once done.
core/org.openjdk.jmc.flightrecorder.rules.jdk/src/main/java/org/openjdk/jmc/flightrecorder/rules/jdk/util/DefaultIItemResultSet.java line 134:
> 132: 				} finally {
> 133: 					exec.shutdown();
> 134: 					exec.awaitTermination(ClassLeakingRule.CONFIGURED_TIMEOUT, TimeUnit.MINUTES);
I believe the proper executor shutdown sequence would be something like this
Suggestion:
				} finally {
				    exec.shutdown();
					try {
						if (!exec.awaitTermination(60, TimeUnit.SECONDS)) {
							exec.shutdownNow();
							
							// possibly wait for other task to respond to cancellation, possibly not needed in this case. But useful to keep, if this code gets extracted away.
							if (!pool.awaitTermination(timeout.clampedLongValueIn(MINUTE), TimeUnit.MINUTES)) {
								// TODO notify error that pool did not terminate
							}
						}
					} catch (InterruptedException ie) {
						exec.shutdownNow();
						Thread.currentThread().interrupt();
					}
-------------
Changes requested by bdutheil (Author).
PR: https://git.openjdk.org/jmc/pull/419
    
    
More information about the jmc-dev
mailing list