Hitting the /logText/progressiveText API of a completed build with very large log file ( XXX MB or X GB or more) exhaust the heap memory.
The Jetty thread handling it looks like this:
"Handling GET /job/testLog/5//logText/progressiveText from 127.0.0.1 : Jetty (winstone)-19" id=19 state=RUNNABLE
at java.base@17.0.8/java.util.zip.Deflater.deflateBufferBytes(Native Method)
at java.base@17.0.8/java.util.zip.Deflater.deflate(Deflater.java:751)
at Jenkins Main ClassLoader//org.eclipse.jetty.server.handler.gzip.GzipResponseAndCallback$GzipBufferCB.compressing(GzipResponseAndCallback.java:410)
at Jenkins Main ClassLoader//org.eclipse.jetty.server.handler.gzip.GzipResponseAndCallback$GzipBufferCB.process(GzipResponseAndCallback.java:370)
at Jenkins Main ClassLoader//org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:262)
at Jenkins Main ClassLoader//org.eclipse.jetty.util.IteratingCallback.iterate(IteratingCallback.java:243)
at Jenkins Main ClassLoader//org.eclipse.jetty.server.handler.gzip.GzipResponseAndCallback.gzip(GzipResponseAndCallback.java:157)
at Jenkins Main ClassLoader//org.eclipse.jetty.server.handler.gzip.GzipResponseAndCallback.write(GzipResponseAndCallback.java:135)
at Jenkins Main ClassLoader//org.eclipse.jetty.server.Response$Wrapper.write(Response.java:768)
at Jenkins Main ClassLoader//org.eclipse.jetty.server.handler.ContextResponse.write(ContextResponse.java:56)
at Jenkins Main ClassLoader//org.eclipse.jetty.ee9.nested.HttpChannel.send(HttpChannel.java:1044)
at Jenkins Main ClassLoader//org.eclipse.jetty.ee9.nested.HttpChannel.sendResponse(HttpChannel.java:1028)
at Jenkins Main ClassLoader//org.eclipse.jetty.ee9.nested.HttpChannel.write(HttpChannel.java:1110)
at Jenkins Main ClassLoader//org.eclipse.jetty.ee9.nested.HttpOutput.channelWrite(HttpOutput.java:277)
at Jenkins Main ClassLoader//org.eclipse.jetty.ee9.nested.HttpOutput.channelWrite(HttpOutput.java:261)
at Jenkins Main ClassLoader//org.eclipse.jetty.ee9.nested.HttpOutput.write(HttpOutput.java:876)
at java.base@17.0.8/java.io.ByteArrayOutputStream.writeTo(ByteArrayOutputStream.java:161)
- locked org.eclipse.jetty.util.ByteArrayOutputStream2@5ff96858
at Jenkins Main ClassLoader//org.eclipse.jetty.io.WriteThroughWriter$Utf8Writer.append(WriteThroughWriter.java:335)
at Jenkins Main ClassLoader//org.eclipse.jetty.io.WriteThroughWriter.write(WriteThroughWriter.java:138)
at Jenkins Main ClassLoader//org.eclipse.jetty.ee9.nested.ResponseWriter.write(ResponseWriter.java:209)
- locked org.eclipse.jetty.io.WriteThroughWriter$Utf8Writer@4cb1d7cd
at org.springframework.security.web.util.OnCommittedResponseWrapper$SaveContextPrintWriter.write(OnCommittedResponseWrapper.java:314)
at java.base@17.0.8/java.io.FilterWriter.write(FilterWriter.java:83)
at org.kohsuke.stapler.framework.io.LineEndNormalizingWriter.write(LineEndNormalizingWriter.java:78)
at org.kohsuke.stapler.framework.io.LineEndNormalizingWriter.write(LineEndNormalizingWriter.java:51)
at org.kohsuke.stapler.framework.io.CharSpool.writeTo(CharSpool.java:86)
at org.kohsuke.stapler.framework.io.LargeText.doProgressTextImpl(LargeText.java:319)
at org.kohsuke.stapler.framework.io.LargeText.doProgressText(LargeText.java:274)
at hudson.console.AnnotatedLargeText.doProgressiveText(AnnotatedLargeText.java:128)
at java.base@17.0.8/java.lang.invoke.LambdaForm$DMH/0x000000013e120400.invokeVirtual(LambdaForm$DMH)
at java.base@17.0.8/java.lang.invoke.LambdaForm$MH/0x000000013ece2800.invoke(LambdaForm$MH)
at java.base@17.0.8/java.lang.invoke.LambdaForm$MH/0x000000013ec9dc00.invoke(LambdaForm$MH)
at java.base@17.0.8/java.lang.invoke.LambdaForm$MH/0x000000013ec9c000.invokeExact_MT(LambdaForm$MH)
at java.base@17.0.8/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
at org.kohsuke.stapler.Function$MethodFunction.invoke(Function.java:484)
at org.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:497)
at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:218)
at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:140)
at org.kohsuke.stapler.MetaClass$12.doDispatch(MetaClass.java:686)
at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:61)
at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:800)
at org.kohsuke.stapler.Stapler.invoke(Stapler.java:938)
at org.kohsuke.stapler.MetaClass$2.doDispatch(MetaClass.java:244)
at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:61)
at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:800)
at org.kohsuke.stapler.Stapler.invoke(Stapler.java:938)
at org.kohsuke.stapler.MetaClass$10.dispatch(MetaClass.java:590)
at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:800)
at org.kohsuke.stapler.Stapler.invoke(Stapler.java:938)
at org.kohsuke.stapler.MetaClass$5.doDispatch(MetaClass.java:369)
at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:61)
at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:800)
at org.kohsuke.stapler.Stapler.invoke(Stapler.java:938)
at org.kohsuke.stapler.Stapler.invoke(Stapler.java:721)
at org.kohsuke.stapler.Stapler.service(Stapler.java:253)
at Jenkins Main ClassLoader//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:587)
at Jenkins Main ClassLoader//org.eclipse.jetty.ee9.servlet.ServletHolder.handle(ServletHolder.java:765)
On the other hand, the console output is not impacted by this and efficiently stream the logs.
The API documentation is not clear about how to stream the data should a REST Client want to do something similar:
Or if it is even possible.
How to Reproduce
- Spin a controller
- Create a pipeline that generates a lot of logs, for example:
node {
sh """
head -c 10073741824 /dev/urandom | base64 --break=1000
"""
}
- Build it
- Once completed, go to $JOB_URL/logText/progressiveText
- Generate a heapdump and observe that the Jetty thread holds everything in memory
cc @jglick who helped confirm this bug.
Originally reported by
allan_burdajewicz, imported from: The /logText/progressiveText API exhaust heap memory on large logs of completed builds
- assignee:
jglick
- status: Closed
- priority: Major
- component(s): core
- label(s): heap, performance, stapler
- resolution: Fixed
- resolved: 2025-05-02T11:39:42+00:00
- votes: 0
- watchers: 3
- imported: 2025-11-24
Raw content of original issue
Hitting the /logText/progressiveText API of a completed build with very large log file ( XXX MB or X GB or more) exhaust the heap memory.
The Jetty thread handling it looks like this:
"Handling GET /job/testLog/5//logText/progressiveText from 127.0.0.1 : Jetty (winstone)-19" id=19 state=RUNNABLE
at java.base@17.0.8/java.util.zip.Deflater.deflateBufferBytes(Native Method)
at java.base@17.0.8/java.util.zip.Deflater.deflate(Deflater.java:751)
at Jenkins Main ClassLoader//org.eclipse.jetty.server.handler.gzip.GzipResponseAndCallback$GzipBufferCB.compressing(GzipResponseAndCallback.java:410)
at Jenkins Main ClassLoader//org.eclipse.jetty.server.handler.gzip.GzipResponseAndCallback$GzipBufferCB.process(GzipResponseAndCallback.java:370)
at Jenkins Main ClassLoader//org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:262)
at Jenkins Main ClassLoader//org.eclipse.jetty.util.IteratingCallback.iterate(IteratingCallback.java:243)
at Jenkins Main ClassLoader//org.eclipse.jetty.server.handler.gzip.GzipResponseAndCallback.gzip(GzipResponseAndCallback.java:157)
at Jenkins Main ClassLoader//org.eclipse.jetty.server.handler.gzip.GzipResponseAndCallback.write(GzipResponseAndCallback.java:135)
at Jenkins Main ClassLoader//org.eclipse.jetty.server.Response$Wrapper.write(Response.java:768)
at Jenkins Main ClassLoader//org.eclipse.jetty.server.handler.ContextResponse.write(ContextResponse.java:56)
at Jenkins Main ClassLoader//org.eclipse.jetty.ee9.nested.HttpChannel.send(HttpChannel.java:1044)
at Jenkins Main ClassLoader//org.eclipse.jetty.ee9.nested.HttpChannel.sendResponse(HttpChannel.java:1028)
at Jenkins Main ClassLoader//org.eclipse.jetty.ee9.nested.HttpChannel.write(HttpChannel.java:1110)
at Jenkins Main ClassLoader//org.eclipse.jetty.ee9.nested.HttpOutput.channelWrite(HttpOutput.java:277)
at Jenkins Main ClassLoader//org.eclipse.jetty.ee9.nested.HttpOutput.channelWrite(HttpOutput.java:261)
at Jenkins Main ClassLoader//org.eclipse.jetty.ee9.nested.HttpOutput.write(HttpOutput.java:876)
at java.base@17.0.8/java.io.ByteArrayOutputStream.writeTo(ByteArrayOutputStream.java:161)
- locked org.eclipse.jetty.util.ByteArrayOutputStream2@5ff96858
at Jenkins Main ClassLoader//org.eclipse.jetty.io.WriteThroughWriter$Utf8Writer.append(WriteThroughWriter.java:335)
at Jenkins Main ClassLoader//org.eclipse.jetty.io.WriteThroughWriter.write(WriteThroughWriter.java:138)
at Jenkins Main ClassLoader//org.eclipse.jetty.ee9.nested.ResponseWriter.write(ResponseWriter.java:209)
- locked org.eclipse.jetty.io.WriteThroughWriter$Utf8Writer@4cb1d7cd
at org.springframework.security.web.util.OnCommittedResponseWrapper$SaveContextPrintWriter.write(OnCommittedResponseWrapper.java:314)
at java.base@17.0.8/java.io.FilterWriter.write(FilterWriter.java:83)
at org.kohsuke.stapler.framework.io.LineEndNormalizingWriter.write(LineEndNormalizingWriter.java:78)
at org.kohsuke.stapler.framework.io.LineEndNormalizingWriter.write(LineEndNormalizingWriter.java:51)
at org.kohsuke.stapler.framework.io.CharSpool.writeTo(CharSpool.java:86)
at org.kohsuke.stapler.framework.io.LargeText.doProgressTextImpl(LargeText.java:319)
at org.kohsuke.stapler.framework.io.LargeText.doProgressText(LargeText.java:274)
at hudson.console.AnnotatedLargeText.doProgressiveText(AnnotatedLargeText.java:128)
at java.base@17.0.8/java.lang.invoke.LambdaForm$DMH/0x000000013e120400.invokeVirtual(LambdaForm$DMH)
at java.base@17.0.8/java.lang.invoke.LambdaForm$MH/0x000000013ece2800.invoke(LambdaForm$MH)
at java.base@17.0.8/java.lang.invoke.LambdaForm$MH/0x000000013ec9dc00.invoke(LambdaForm$MH)
at java.base@17.0.8/java.lang.invoke.LambdaForm$MH/0x000000013ec9c000.invokeExact_MT(LambdaForm$MH)
at java.base@17.0.8/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
at org.kohsuke.stapler.Function$MethodFunction.invoke(Function.java:484)
at org.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:497)
at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:218)
at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:140)
at org.kohsuke.stapler.MetaClass$12.doDispatch(MetaClass.java:686)
at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:61)
at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:800)
at org.kohsuke.stapler.Stapler.invoke(Stapler.java:938)
at org.kohsuke.stapler.MetaClass$2.doDispatch(MetaClass.java:244)
at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:61)
at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:800)
at org.kohsuke.stapler.Stapler.invoke(Stapler.java:938)
at org.kohsuke.stapler.MetaClass$10.dispatch(MetaClass.java:590)
at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:800)
at org.kohsuke.stapler.Stapler.invoke(Stapler.java:938)
at org.kohsuke.stapler.MetaClass$5.doDispatch(MetaClass.java:369)
at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:61)
at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:800)
at org.kohsuke.stapler.Stapler.invoke(Stapler.java:938)
at org.kohsuke.stapler.Stapler.invoke(Stapler.java:721)
at org.kohsuke.stapler.Stapler.service(Stapler.java:253)
at Jenkins Main ClassLoader//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:587)
at Jenkins Main ClassLoader//org.eclipse.jetty.ee9.servlet.ServletHolder.handle(ServletHolder.java:765)
On the other hand, the console output is not impacted by this and efficiently stream the logs.
The API documentation is not clear about how to stream the data should a REST Client want to do something similar:
Or if it is even possible.
How to Reproduce
- Spin a controller
- Create a pipeline that generates a lot of logs, for example:
node {
sh """
head -c 10073741824 /dev/urandom | base64 --break=1000
"""
}
- Build it
- Once completed, go to $JOB_URL/logText/progressiveText
- Generate a heapdump and observe that the Jetty thread holds everything in memory
cc @jglick who helped confirm this bug.
Hitting the /logText/progressiveText API of a completed build with very large log file ( XXX MB or X GB or more) exhaust the heap memory.
The Jetty thread handling it looks like this:
On the other hand, the console output is not impacted by this and efficiently stream the logs.
The API documentation is not clear about how to stream the data should a REST Client want to do something similar:
Or if it is even possible.
How to Reproduce
node { sh """ head -c 10073741824 /dev/urandom | base64 --break=1000 """ }cc @jglick who helped confirm this bug.
Originally reported by
allan_burdajewicz, imported from: The /logText/progressiveText API exhaust heap memory on large logs of completed builds
Raw content of original issue
Or if it is even possible.
How to Reproduce
node { sh """ head -c 10073741824 /dev/urandom | base64 --break=1000 """ }cc @jglick who helped confirm this bug.