libfaketime icon indicating copy to clipboard operation
libfaketime copied to clipboard

Java program uses 100% CPU with libfaketime

Open woshikid opened this issue 1 year ago • 16 comments

I uses libfaketime to change the time in docker container. But when I run Java programs with libfaketime, I noticed that it uses 100% of the cpu resources even no java code is using cpu.

It can be reproduced by run docker run -it eclipse-temurin:11 bash and install libfaketime by apt update && apt install libfaketime or build from source. And with java code Test.java

public class Test {
    public static void main(String args[]) throws Exception {
        System.out.println("waiting for input");
        System.in.read();
    }
}

when running this test code with libfaketime: LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1 java Test it takes all the CPU resources: image

I've tested the java 8, 11, and 17. Java 8 and 11 both have this issue and java 17 works fine.

woshikid avatar May 05 '23 08:05 woshikid

I have a similar issue, we have a java application running in a docker container, we're using LD_PRELOAD and FAKETIME_DONT_FAKE_MONOTIC environment variables as expressed in the README, the thing is: this worked fine with jdk 11.0.17 However, with the new jdk 11.0.19 the cpu usage skyrocketed without explanation, removing faketime appears to solve the high cpu usage so we know for sure that there's some incompatibility with jdk 11.0.19 and faketime.

pedroyzkrak avatar May 26 '23 15:05 pedroyzkrak

@woshikid Could you tell us which precise worked version did you use for java17, 17.0.x?

dawsondong avatar Jun 29 '23 02:06 dawsondong

@dawsondong I used docker eclipse-temurin:17, and the version is openjdk "17.0.7" 2023-04-18

woshikid avatar Jun 29 '23 12:06 woshikid

I have same issue too. In my case, the problem is mysql on macos13.1(M1). My faketime version is 0.9.10 install by brew. And I use .faketimerc set faketime. faketime_cpu

viquu avatar Aug 24 '23 08:08 viquu

I have the same problem using Forgerock IDM and OpenJDK Runtime Environment 17.09 (build 17.0.9+8-LTS).

christian-scheible avatar Nov 30 '23 09:11 christian-scheible

Same problem here. I tested with Ubuntu in a Docker Image. I used the following program versions:

  • Ubuntu 18.04, libfaketime 0.9.7-2, Java 8 and Java 11 => The problem does not exist
  • Ubuntu 22.04, libfaketime 0.9.8-9, Java 8 and Java 11 => The problem exists
  • Ubuntu 22.04, libfaketime 0.9.7-3, Java 8 and Java 11 => The problem does not exist
  • Ubuntu 22.04, libfaketime 0.9.8-9, Java 17 => The problem exists
  • Ubuntu 22.04, libfaketime 0.9.10-2.1, Java 11 => The problem exists

I did some analysis. To me it seems like the JVM compiler threads are causing the high CPU usage. Usually they should only use the CPU right after the start of the program. But with the new libfaketime version, they do not stop. See the following screenshot: threads_libfaketime

eriknellessen avatar Dec 12 '23 10:12 eriknellessen

I have an update regarding this issue. As I genuinely require this library for testing purposes, I endeavored to build various versions of libfaketime independently.

Here is my current setup:

I'm utilizing a base image with Debian GNU/Linux 11 (bullseye) and OpenJDK 17.09 (OpenJDK Runtime Environment Zulu17.46+19-CA (build 17.0.9+8-LTS)).

For anyone experiencing similar problems and seeking a workaround, here's what I did:

I experimented with different versions of libfaketime, and up until version 0.9.10, the issue does not exist.

  • libfaketime 0.9.7 worked
  • libfaketime 0.9.8 worked
  • libfaketime 0.9.9 worked
  • libfaketime 0.9.10 didn't work
  • libfaketime master didn't work

For anyone haveing similar problems and looking for a work around this is what I did:

RUN apt-get update && apt-get install -y \
    wget \
    unzip \
    make \
    gcc \
 && rm -rf /var/lib/apt/lists/*

RUN mkdir faketime && \
    cd faketime && \
    wget https://github.com/wolfcw/libfaketime/archive/refs/tags/v0.9.9.zip && \
    unzip v0.9.9.zip && \
    cd libfaketime-0.9.9 && \
    make install

After that LD_PRELOAD has to be set to this value:

LD_PRELOAD: "/usr/local/lib/faketime/libfaketime.so.1"

christian-scheible avatar Feb 02 '24 09:02 christian-scheible

Thanks for this update! Any chance you could go the extra mile and figure out which commit between 0.9.9 and 0.9.10 breaks it for you?

Based on @eriknellessen 's comment it seems like pre-0.9.9 versions may have this problem as well (unless Ubuntu backported something, I don't know), but it at least may give us a hint where to look closer when it comes to JDK compatibility.

wolfcw avatar Feb 02 '24 19:02 wolfcw

Hi wolfcw,

sure I did what you suggested and for me until commit: 36090e8ceba3dd0cc9478403eacf5949530ab6d9 everything was fine.

So:

  • 0e61d3d1917f530b5e3f66db2ed5dd6acd20e798 worked
  • 36090e8ceba3dd0cc9478403eacf5949530ab6d9 didn't work

christian-scheible avatar Feb 05 '24 09:02 christian-scheible

@christian-scheible That's very helpful, thank you very much!

It's the commit that changed the auto-detection for the necessity of FORCE_MONOTONIC_FIX based on the system's glibc version. Different glibc versions behave differently in the context of the pthread_cond_timedwait() function, and correlating this with @eriknellessen 's list it seems like JDK might have the same or a similar issue with libfaketime independent of glibc.

Could you eventually try to activate / de-activate libfaketime's fixing attempts by setting the environment variable FAKETIME_FORCE_MONOTONIC_FIX to either 1 (activate) or 0 (de-activate) and check whether this changes anything (also with newer versions such as current HEAD)?

Also, could you tell which glibc version is used on your testing system?

wolfcw avatar Feb 05 '24 17:02 wolfcw

@wolfcw, happy to help. I like libfaketime, so it's great to be able to contribute.

I've tested commit versions 36090e8ceba3dd0cc9478403eacf5949530ab6d9 and the latest, f32986867addc9d22b0fab29c1c927f079d44ac1. Setting FAKETIME_FORCE_MONOTONIC_FIX to 0 fixed it for me.

The glibc version on my testing system is:

ldd (Debian GLIBC 2.31-13+deb11u7) 2.31

christian-scheible avatar Feb 06 '24 13:02 christian-scheible

Great to know, thank you very much. Maybe the others could check as well whether this is a suitable workaround, and if so, we'll look into automating this.

wolfcw avatar Feb 07 '24 11:02 wolfcw

Hi, just wanted you to know we got the same problem using temurin-21 when upgrading to spring-boot 3.2.2 (probably the cause). Solved it also by setting the FAKETIME_FORCE_MONOTONIC_FIX=0 using version 0.9.10

pertyjons avatar Feb 19 '24 13:02 pertyjons

😭 well, to me the problem still exists with FAKETIME_FORCE_MONOTONIC_FIX=0. I just tested this workaround on the code as I posted. FAKETIME_FORCE_MONOTONIC_FIX=0 LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfak etime.so.1 java Test and it still eat up all the cpu time.

the base docker image is eclipse-temurin:11 and the glibc version is ldd (Ubuntu GLIBC 2.35-0ubuntu3.6) 2.35

woshikid avatar Feb 20 '24 03:02 woshikid

I've tested the HEAD version of libfaketime, the workaround FAKETIME_FORCE_MONOTONIC_FIX=0 works! The libfaketime in image eclipse-temurin:11 by apt install libfaketime is 0.9.8-9, and that version didn't work with this workaround.

woshikid avatar Feb 20 '24 07:02 woshikid

This workaround has side effects (https://github.com/wolfcw/libfaketime/issues/460)

on Ubuntu (ldd (Ubuntu GLIBC 2.35-0ubuntu3.6) 2.35) with HEAD version of libfaketime and Java code Thread.sleep(1000); when set FAKETIME_FORCE_MONOTONIC_FIX=0 Java 11 (openjdk version "11.0.22" 2024-01-16): works fine. Java 17 (openjdk version "17.0.10" 2024-01-16): hangs forever. Java 21 (openjdk version "21.0.2" 2024-01-16 LTS): hangs forever.

So we have to find other way.

woshikid avatar Feb 23 '24 10:02 woshikid