Fix memory leak on closure compilation

This commit is contained in:
Dominik Przybysz 2017-05-31 09:53:38 +02:00
parent 2b57ba0806
commit 4fb0c9cfce
5 changed files with 17 additions and 9 deletions

View file

@ -22,6 +22,8 @@ import pl.touk.mockserver.api.response.Parameter
import javax.xml.bind.JAXBContext import javax.xml.bind.JAXBContext
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.CopyOnWriteArraySet import java.util.concurrent.CopyOnWriteArraySet
import java.util.concurrent.Executor
import java.util.concurrent.Executors
import static pl.touk.mockserver.server.Util.createResponse import static pl.touk.mockserver.server.Util.createResponse
@ -32,12 +34,14 @@ class HttpMockServer {
private final Map<Integer, HttpServerWraper> childServers = new ConcurrentHashMap<>() private final Map<Integer, HttpServerWraper> childServers = new ConcurrentHashMap<>()
private final Set<String> mockNames = new CopyOnWriteArraySet<>() private final Set<String> mockNames = new CopyOnWriteArraySet<>()
private final ConfigObject configuration = new ConfigObject() private final ConfigObject configuration = new ConfigObject()
private final Executor executor
private static private static
final JAXBContext requestJaxbContext = JAXBContext.newInstance(AddMock.package.name, AddMock.classLoader) final JAXBContext requestJaxbContext = JAXBContext.newInstance(AddMock.package.name, AddMock.classLoader)
HttpMockServer(int port = 9999, ConfigObject initialConfiguration = new ConfigObject()) { HttpMockServer(int port = 9999, ConfigObject initialConfiguration = new ConfigObject(), int threads = 10) {
httpServerWraper = new HttpServerWraper(port) executor = Executors.newFixedThreadPool(threads)
httpServerWraper = new HttpServerWraper(port, executor)
initialConfiguration.values()?.each { ConfigObject co -> initialConfiguration.values()?.each { ConfigObject co ->
addMock(co) addMock(co)
@ -172,7 +176,7 @@ class HttpMockServer {
private HttpServerWraper getOrCreateChildServer(int mockPort) { private HttpServerWraper getOrCreateChildServer(int mockPort) {
HttpServerWraper child = childServers[mockPort] HttpServerWraper child = childServers[mockPort]
if (!child) { if (!child) {
child = new HttpServerWraper(mockPort) child = new HttpServerWraper(mockPort, executor)
childServers.put(mockPort, child) childServers.put(mockPort, child)
} }
return child return child

View file

@ -5,7 +5,7 @@ import com.sun.net.httpserver.HttpServer
import groovy.transform.PackageScope import groovy.transform.PackageScope
import groovy.util.logging.Slf4j import groovy.util.logging.Slf4j
import java.util.concurrent.Executors import java.util.concurrent.Executor
@Slf4j @Slf4j
@PackageScope @PackageScope
@ -15,11 +15,11 @@ class HttpServerWraper {
private List<ContextExecutor> executors = [] private List<ContextExecutor> executors = []
HttpServerWraper(int port) { HttpServerWraper(int port, Executor executor) {
this.port = port this.port = port
InetSocketAddress addr = new InetSocketAddress(Inet4Address.getByName("0.0.0.0"), port) InetSocketAddress addr = new InetSocketAddress(Inet4Address.getByName("0.0.0.0"), port)
httpServer = HttpServer.create(addr, 0) httpServer = HttpServer.create(addr, 0)
httpServer.executor = Executors.newWorkStealingPool() httpServer.executor = executor
log.info("Http server starting on port $port...") log.info("Http server starting on port $port...")
httpServer.start() httpServer.start()
log.info('Http server is started') log.info('Http server is started')

View file

@ -21,9 +21,11 @@ class Main {
private static HttpMockServer startMockServer(String... args) { private static HttpMockServer startMockServer(String... args) {
switch (args.length) { switch (args.length) {
case 1: case 1:
return new HttpMockServer(args[0] as int) return new HttpMockServer(args[0] as int, new ConfigObject())
case 2: case 2:
return new HttpMockServer(args[0] as int, new ConfigSlurper().parse(new File(args[1]).toURI().toURL())) return new HttpMockServer(args[0] as int, new ConfigSlurper().parse(new File(args[1]).toURI().toURL()))
case 3:
return new HttpMockServer(args[0] as int, new ConfigSlurper().parse(new File(args[1]).toURI().toURL()), args[2] as int)
default: default:
return new HttpMockServer() return new HttpMockServer()
} }

View file

@ -103,7 +103,9 @@ class Mock implements Comparable<Mock> {
} }
compilerConfiguration.addCompilationCustomizers(customizer) compilerConfiguration.addCompilationCustomizers(customizer)
GroovyShell sh = new GroovyShell(this.class.classLoader, compilerConfiguration); GroovyShell sh = new GroovyShell(this.class.classLoader, compilerConfiguration);
return sh.evaluate(predicate) as Closure Closure closure = sh.evaluate(predicate) as Closure
sh.resetLoadedClasses()
return closure
} }
void setResponse(String response) { void setResponse(String response) {

View file

@ -24,7 +24,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven-compiler-plugin.version>3.1</maven-compiler-plugin.version> <maven-compiler-plugin.version>3.1</maven-compiler-plugin.version>
<groovy.version>2.4.1</groovy.version> <groovy.version>2.4.11</groovy.version>
<httpclient.version>4.3.5</httpclient.version> <httpclient.version>4.3.5</httpclient.version>
<spock-core.version>1.0-groovy-2.4</spock-core.version> <spock-core.version>1.0-groovy-2.4</spock-core.version>
<commons-lang3.version>3.3.2</commons-lang3.version> <commons-lang3.version>3.3.2</commons-lang3.version>