-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathCollectionAnalyzerAspect.java
More file actions
100 lines (87 loc) · 3.62 KB
/
CollectionAnalyzerAspect.java
File metadata and controls
100 lines (87 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package de.codecentric.performance.memory;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
* Note: this Aspect is for demo purpose only and is not threadsafe!
*/
@Aspect
@SuppressWarnings("rawtypes")
public final class CollectionAnalyzerAspect {
private final Map<Integer, CollectionStatistics> statistics = new HashMap<Integer, CollectionStatistics>();
/**
* Returns a CollectionStatistics instance for the given collection.
*/
private CollectionStatistics getStatistics(Object targetCollection) {
// we use the IdentityHashCode as key for our statistics storage
int identityHashCode = System.identityHashCode(targetCollection);
CollectionStatistics stats = statistics.get(identityHashCode);
if (stats == null) {
stats = new CollectionStatistics(targetCollection.getClass().getName(), identityHashCode);
statistics.put(identityHashCode, stats);
}
return stats;
}
/**
* Returns a developer usable String for the line of code the joinpoint is acting on.
* <code>de.codecentric.performance.LeakDemo:19</code>
*/
private String getLocation(final JoinPoint thisJoinPoint) {
return thisJoinPoint.getStaticPart().getSourceLocation().getWithinType().getName() + ":"
+ thisJoinPoint.getStaticPart().getSourceLocation().getLine();
}
@Before(" call(boolean java.util.List.add(..))")
public void trackListAdds(final JoinPoint thisJoinPoint) {
List target = (List) thisJoinPoint.getTarget();
CollectionStatistics stats = getStatistics(target);
stats.recordWrite(getLocation(thisJoinPoint));
stats.evaluate(target.size());
}
@Before(" call(* java.util.List.get(..))")
public void trackListGets(final JoinPoint thisJoinPoint) {
List target = (List) thisJoinPoint.getTarget();
CollectionStatistics stats = getStatistics(target);
stats.recordRead(getLocation(thisJoinPoint));
stats.evaluate(target.size());
}
@Before(" call(* java.util.List.remove(..))")
public void trackListRemoves(final JoinPoint thisJoinPoint) {
List target = (List) thisJoinPoint.getTarget();
CollectionStatistics stats = getStatistics(target);
stats.recordDelete(getLocation(thisJoinPoint));
stats.evaluate(target.size());
}
/**
* We use a Map ourselves which we do not want to track (would recurse indefinitely)).
*/
@Before(" call(* java.util.Map.put(..)) && !this(de.codecentric.performance.memory.CollectionAnalyzerAspect)")
public void trackMapPuts(final JoinPoint thisJoinPoint) {
Map target = (Map) thisJoinPoint.getTarget();
CollectionStatistics stats = getStatistics(target);
stats.recordWrite(getLocation(thisJoinPoint));
stats.evaluate(target.size());
}
/**
* We use a Map ourselves which we do not want to track (would recurse indefinitely)).
*/
@Before(" call(* java.util.Map.get(..)) && !this(de.codecentric.performance.memory.CollectionAnalyzerAspect)")
public void trackMapGets(final JoinPoint thisJoinPoint) {
Map target = (Map) thisJoinPoint.getTarget();
CollectionStatistics stats = getStatistics(target);
stats.recordRead(getLocation(thisJoinPoint));
stats.evaluate(target.size());
}
/**
* We use a Map ourselves which we do not want to track (would recurse indefinitely)).
*/
@Before(" call(* java.util.Map.remove(..)) && !this(de.codecentric.performance.memory.CollectionAnalyzerAspect)")
public void trackMapRemoves(final JoinPoint thisJoinPoint) {
Map target = (Map) thisJoinPoint.getTarget();
CollectionStatistics stats = getStatistics(target);
stats.recordDelete(getLocation(thisJoinPoint));
stats.evaluate(target.size());
}
}