-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[adservice] add adServiceManualGC featureflag (#1463)
* [adservice] add adServiceManualGC featureflag * update changelog * [adservice] address PR comment --------- Co-authored-by: Pierre Tessier <[email protected]>
- Loading branch information
Showing
5 changed files
with
175 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 80 additions & 0 deletions
80
src/adservice/src/main/java/oteldemo/problempattern/GarbageCollectionTrigger.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package oteldemo.problempattern; | ||
|
||
import java.lang.management.ManagementFactory; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
|
||
/** | ||
* The GarbageCollectionTrigger class is responsible for triggering manual garbage collection | ||
* at specified intervals to simulate memory pressure and measure the impact on performance. | ||
*/ | ||
public class GarbageCollectionTrigger { | ||
private static final Logger logger = LogManager.getLogger(GarbageCollectionTrigger.class.getName()); | ||
|
||
private final long gc_delay; | ||
private final int finalize_delay; | ||
private final int maxObjects; | ||
|
||
private long lastGC = 0; | ||
|
||
private final MemoryUtils memUtils; | ||
|
||
/** | ||
* Constructs a new GarbageCollectionTrigger with default values. | ||
*/ | ||
public GarbageCollectionTrigger() { | ||
memUtils = new MemoryUtils(ManagementFactory.getMemoryMXBean()); | ||
gc_delay = TimeUnit.SECONDS.toMillis(10); | ||
finalize_delay = 500; | ||
maxObjects = 500000; | ||
} | ||
|
||
/** | ||
* Triggers manual garbage collection at specified intervals and measures the impact on performance. | ||
* It creates Entry objects to fill up memory and initiates garbage collection. | ||
*/ | ||
public void doExecute() { | ||
if (System.currentTimeMillis() - lastGC > gc_delay) { | ||
logger.info("Triggering a manual garbage collection, next one in " + (gc_delay/1000) + " seconds."); | ||
// clear old data, we want to clear old Entry objects, because their finalization is expensive | ||
System.gc(); | ||
|
||
long total = 0; | ||
for (int i = 0; i < 10; i++) { | ||
while (memUtils.getHeapUsage() < 0.9 && memUtils.getObjectPendingFinalizationCount() < maxObjects) { | ||
new Entry(); | ||
} | ||
long start = System.currentTimeMillis(); | ||
System.gc(); | ||
total += System.currentTimeMillis() - start; | ||
} | ||
logger.info("The artificially triggered GCs took: " + total + " ms"); | ||
lastGC = System.currentTimeMillis(); | ||
} | ||
|
||
} | ||
|
||
/** | ||
* The Entry class represents objects created for the purpose of triggering garbage collection. | ||
*/ | ||
private class Entry { | ||
/** | ||
* Overrides the finalize method to introduce a delay, simulating finalization during garbage collection. | ||
* | ||
* @throws Throwable If an exception occurs during finalization. | ||
*/ | ||
@SuppressWarnings("removal") | ||
@Override | ||
protected void finalize() throws Throwable { | ||
TimeUnit.MILLISECONDS.sleep(finalize_delay); | ||
super.finalize(); | ||
} | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
src/adservice/src/main/java/oteldemo/problempattern/MemoryUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package oteldemo.problempattern; | ||
|
||
import java.lang.management.MemoryMXBean; | ||
import java.lang.management.MemoryUsage; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
|
||
|
||
/** | ||
* This class provides JVM heap related utility methods. | ||
*/ | ||
public class MemoryUtils { | ||
|
||
private static final Logger logger = LogManager.getLogger(MemoryUtils.class.getName()); | ||
|
||
private static final long NO_HEAP_LIMIT = -1; | ||
|
||
private final MemoryMXBean memoryBean; | ||
|
||
/** | ||
* @param memoryBean defines which {@link MemoryMXBean} is to use | ||
*/ | ||
public MemoryUtils(MemoryMXBean memoryBean) { | ||
this.memoryBean = memoryBean; | ||
} | ||
|
||
|
||
/** | ||
* @return The current heap usage as a decimal number between 0.0 and 1.0. | ||
* That is, if the returned value is 0.85, 85% of the max heap is used. | ||
* | ||
* If no max heap is set, the method returns -1.0. | ||
*/ | ||
public double getHeapUsage() { | ||
MemoryUsage heapProps = memoryBean.getHeapMemoryUsage(); | ||
long heapUsed = heapProps.getUsed(); | ||
long heapMax = heapProps.getMax(); | ||
|
||
if (heapMax == NO_HEAP_LIMIT) { | ||
if (logger.isDebugEnabled()) { | ||
logger.debug("No maximum heap is set"); | ||
} | ||
return NO_HEAP_LIMIT; | ||
} | ||
|
||
|
||
double heapUsage = (double) heapUsed / heapMax; | ||
if (logger.isDebugEnabled()) { | ||
logger.debug("Current heap usage is {0} percent" + (heapUsage * 100)); | ||
} | ||
return heapUsage; | ||
} | ||
|
||
/** | ||
* see {@link MemoryMXBean#getObjectPendingFinalizationCount()} | ||
*/ | ||
public int getObjectPendingFinalizationCount() { | ||
return memoryBean.getObjectPendingFinalizationCount(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters