1 /* 2 * Copyright (c) 2002-2025 Gargoyle Software Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * https://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 package org.htmlunit.javascript.background; 16 17 import org.htmlunit.MockWebConnection; 18 import org.htmlunit.SimpleWebTestCase; 19 import org.htmlunit.WebClient; 20 import org.htmlunit.util.MemoryLeakDetector; 21 import org.junit.Test; 22 23 /** 24 * <p>Tests for memory leaks. This test passes when run independently in Eclipse or via 25 * Maven (mvn test -Dtest=MemoryLeakTest), but not when all tests are run via Maven 26 * (mvn test). Note that this probably constitutes a false positive, meaning that the 27 * window isn't leaked in this situation -- we just can't get the JVM to GC it because 28 * there is no surefire way to force complete garbage collection.</p> 29 * 30 * <p>All suspected memory leaks should be verified with a profiler before a fix and/or 31 * unit test is committed. In JProfiler, for example, you can run a unit test and tell 32 * the profiler to keep the VM alive when it has finished running; once it has finished 33 * running you can go to the Heap Walker, take a snapshot of the heap, sort the resultant 34 * table by class name and find the class you're interested in, double-click on it, choose 35 * to view References to instances of this class, then right-click on the class and choose 36 * Show Paths to GC Root. This will give you a list of references which need to be 37 * eliminated. Once you have a fix, repeat the above steps in order to verify that the 38 * fix works.</p> 39 * 40 * @author Daniel Gredler 41 */ 42 public class MemoryLeakTest extends SimpleWebTestCase { 43 44 /** 45 * Empty test which keeps Maven/JUnit from complaining about a test class with no tests. This test 46 * class cannot be run automatically via Maven for the reasons outlined above. 47 * @throws Exception if an error occurs 48 */ 49 @Test 50 public void leaks() throws Exception { 51 // windowLeaks(); 52 } 53 54 /** 55 * Verifies that windows don't get leaked, especially when there are long-running background JS tasks 56 * scheduled via <tt>setTimeout</tt> or <tt>setInterval</tt>. See the following bugs: 57 * http://sourceforge.net/p/htmlunit/bugs/639/ 58 * http://sourceforge.net/p/htmlunit/bugs/648/ 59 * 60 * @throws Exception if an error occurs 61 */ 62 protected void windowLeaks() throws Exception { 63 final MemoryLeakDetector detector = new MemoryLeakDetector(); 64 65 try (WebClient client = new WebClient()) { 66 detector.register("w", client.getCurrentWindow()); 67 68 final MockWebConnection conn = new MockWebConnection(); 69 conn.setResponse(URL_FIRST, 70 DOCTYPE_HTML + "<html><body><script>setInterval('alert(1)',5000)</script></body></html>"); 71 client.setWebConnection(conn); 72 73 client.getPage(URL_FIRST); 74 } 75 assertTrue("Window can't be garbage collected.", detector.canBeGCed("w")); 76 } 77 78 }