changeset 1586:67b1c0156c52

Only load profiling jvm-agent once Reviewed-by: vanaltj Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2014-December/011898.html
author Omair Majid <omajid@redhat.com>
date Wed, 03 Dec 2014 11:54:37 -0500
parents 574c6023b53f
children 41787389d6b2
files vm-profiler/agent/src/main/java/com/redhat/thermostat/vm/profiler/agent/internal/VmProfiler.java vm-profiler/agent/src/test/java/com/redhat/thermostat/vm/profiler/agent/internal/VmProfilerTest.java
diffstat 2 files changed, 43 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/vm-profiler/agent/src/main/java/com/redhat/thermostat/vm/profiler/agent/internal/VmProfiler.java	Wed Dec 03 11:53:17 2014 -0500
+++ b/vm-profiler/agent/src/main/java/com/redhat/thermostat/vm/profiler/agent/internal/VmProfiler.java	Wed Dec 03 11:54:37 2014 -0500
@@ -72,6 +72,7 @@
 
     private static final Logger logger = LoggingUtils.getLogger(VmProfiler.class);
 
+    private final List<Integer> vmsWithAgentLoaded = new ArrayList<>();
     private final List<Integer> currentlyProfiledVmPids = new ArrayList<>();
 
     private final VmIdToPidMapper vmIdToPid = new VmIdToPidMapper();
@@ -118,6 +119,7 @@
             logger.warning(e.getMessage());
         }
         vmIdToPid.remove(vmId, pid);
+        vmsWithAgentLoaded.remove((Integer)pid);
     }
 
     private void disableProfilerIfActive(String vmId, int pid) throws ProfilerException {
@@ -136,12 +138,15 @@
             throw new ProfilerException("Already profiling the VM");
         }
 
-        // TODO make this adjustable at run-time
-        // eg: asmJarPath + ":" + agentJarPath;
-        String jarsToLoad = "";
-        logger.info("Asking " + pid + " to load agent '" + agentJarPath + "' with arguments '" + jarsToLoad + "'");
-        // FIXME Only load the first time
-        remote.loadAgentIntoPid(pid, agentJarPath, jarsToLoad);
+        if (!vmsWithAgentLoaded.contains((Integer)pid)) {
+            // TODO make this adjustable at run-time
+            // eg: asmJarPath + ":" + agentJarPath;
+            String jarsToLoad = "";
+            logger.info("Asking " + pid + " to load agent '" + agentJarPath + "' with arguments '" + jarsToLoad + "'");
+
+            remote.loadAgentIntoPid(pid, agentJarPath, jarsToLoad);
+            vmsWithAgentLoaded.add(pid);
+        }
 
         remote.startProfiling(pid);
 
--- a/vm-profiler/agent/src/test/java/com/redhat/thermostat/vm/profiler/agent/internal/VmProfilerTest.java	Wed Dec 03 11:53:17 2014 -0500
+++ b/vm-profiler/agent/src/test/java/com/redhat/thermostat/vm/profiler/agent/internal/VmProfilerTest.java	Wed Dec 03 11:54:37 2014 -0500
@@ -38,6 +38,7 @@
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
@@ -125,6 +126,37 @@
         verifyNoMoreInteractions(remote);
     }
 
+    @Test
+    public void onlyLoadsAgentOnceForRepeatedProfiling() throws Exception {
+        final String FILE = "foobar";
+        when(remote.getProfilingDataFile(PID)).thenReturn(FILE);
+
+        profiler.vmStarted(VM_ID, PID);
+        profiler.startProfiling(VM_ID);
+        profiler.stopProfiling(VM_ID);
+        profiler.startProfiling(VM_ID);
+
+        verify(remote, times(1)).loadAgentIntoPid(PID, AGENT_JAR, "");
+        verify(remote, times(2)).startProfiling(PID);
+    }
+
+    @Test
+    public void loadsAgentMultipleTimesForNewProcesses() throws Exception {
+        final String FILE = "foobar";
+        when(remote.getProfilingDataFile(PID)).thenReturn(FILE);
+
+        profiler.vmStarted(VM_ID, PID);
+        profiler.startProfiling(VM_ID);
+        profiler.stopProfiling(VM_ID);
+        profiler.vmStopped(VM_ID, PID);
+        // it's not likely that the vmId and the pid will be reused, but just to be sure
+        profiler.vmStarted(VM_ID, PID);
+        profiler.startProfiling(VM_ID);
+
+        verify(remote, times(2)).loadAgentIntoPid(PID, AGENT_JAR, "");
+        verify(remote, times(2)).startProfiling(PID);
+    }
+
     @Test (expected=ProfilerException.class)
     public void doesNotStopProfilingAnUnknownVm() throws Exception {
         profiler.stopProfiling(VM_ID);
@@ -149,7 +181,6 @@
 
     @Test
     public void stoppingProfilingMakesInvokesStopUsingRmiAndUploadsData() throws Exception {
-
         final String FILE = "foobar";
         when(remote.getProfilingDataFile(PID)).thenReturn(FILE);