提交 cd5c5821 编写于 作者: M maoliang.ml 提交者: mmyxym

[GC] Port G1ElasticHeap to dragonwell

Summary: G1ElasticHeap to support heap shrink/expansion in runtime

Test Plan:
test/elastic-heap/

Reviewers:
luchsh, sanhong

Issue:
https://github.com/alibaba/dragonwell8/issues/46

CR:
https://github.com/alibaba/dragonwell8_jdk/pull/1
上级 c724eac3
......@@ -557,7 +557,9 @@ EXCLUDE_PROPWARN_PKGS = com.sun.java.swing.plaf.windows \
#
EXPORTED_PRIVATE_PKGS = com.oracle.net \
com.oracle.nio \
com.alibaba.jwarmup
com.alibaba.jwarmup \
com.alibaba.management \
com.alibaba.jvm.gc
$(IMAGES_OUTPUTDIR)/symbols/_the.symbols: $(IMAGES_OUTPUTDIR)/lib/rt.jar
$(RM) -r $(IMAGES_OUTPUTDIR)/symbols/META-INF/sym
......
......@@ -2557,4 +2557,6 @@ java/awt/event/AdjustmentEvent
java/awt/MenuBar
sun/awt/X11/XErrorEvent
com/alibaba/jwarmup/JWarmUp
com/alibaba/management
com/alibaba/jvm/gc
# eea35d9d56e0006e
......@@ -142,6 +142,7 @@ LIBJAVA_SRC_DIRS += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/l
$(JDK_TOPDIR)/src/share/native/java/security \
$(JDK_TOPDIR)/src/share/native/common \
$(JDK_TOPDIR)/src/share/native/com/alibaba/jwarmup \
$(JDK_TOPDIR)/src/share/native/com/alibaba/jvm/gc \
$(JDK_TOPDIR)/src/share/native/sun/misc \
$(JDK_TOPDIR)/src/share/native/sun/reflect \
$(JDK_TOPDIR)/src/share/native/java/util \
......
......@@ -216,6 +216,7 @@ SUNWprivate_1.1 {
Java_java_lang_System_setOut0;
Java_java_lang_Thread_registerNatives;
Java_com_alibaba_jwarmup_JWarmUp_registerNatives;
Java_com_alibaba_jvm_gc_ElasticHeapMXBeanImpl_registerNatives;
Java_java_lang_Throwable_fillInStackTrace;
Java_java_lang_Throwable_getStackTraceDepth;
Java_java_lang_Throwable_getStackTraceElement;
......
......@@ -11,6 +11,7 @@ text: .text%Java_java_lang_Object_registerNatives;
text: .text%Java_java_lang_System_registerNatives;
text: .text%Java_java_lang_Thread_registerNatives;
text: .text%Java_com_alibaba_jwarmup_JWarmUp_registerNatives;
text: .text%Java_com_alibaba_jvm_gc_ElasticHeapMXBeanImpl_registerNatives;
text: .text%Java_java_security_AccessController_getStackAccessControlContext;
text: .text%Java_java_security_AccessController_getInheritedAccessControlContext;
text: .text%Java_java_lang_ClassLoader_registerNatives;
......
/*
* Copyright (c) 2019 Alibaba Group Holding Limited. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Alibaba designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.alibaba.jvm.gc;
import com.alibaba.management.ElasticHeapMXBean;
import com.alibaba.management.ElasticHeapEvaluationMode;
import sun.management.Util;
import javax.management.ObjectName;
import sun.security.action.GetBooleanAction;
import java.security.AccessController;
/**
* Implementation class for ElasticHeapMXBean.
*/
public class ElasticHeapMXBeanImpl implements ElasticHeapMXBean {
private static native void registerNatives();
static {
registerNatives();
ELASTIC_HEAP_ENABLED = AccessController.doPrivileged(
new GetBooleanAction("com.alibaba.jvm.gc.ElasticHeapEnabled"));
}
private final static String ELASTIC_HEAP_MXBEAN_NAME = "com.alibaba.management:type=ElasticHeap";
// value of property "com.alibaba.jvm.gc.elasticHeapEnabled"
private static final boolean ELASTIC_HEAP_ENABLED;
private static void checkElasticHeapEnabled() {
if (!ELASTIC_HEAP_ENABLED) {
throw new UnsupportedOperationException("-XX:+G1ElasticHeap is not enabled");
}
}
@Override
public ElasticHeapEvaluationMode getEvaluationMode() {
checkElasticHeapEnabled();
ElasticHeapEvaluationMode[] modes = ElasticHeapEvaluationMode.values();
int mode = getEvaluationModeImpl();
// Keap the number aligned with Hotspot
assert mode < modes.length;
return modes[mode];
}
@Override
public void setYoungGenCommitPercent(int percent) {
checkElasticHeapEnabled();
setYoungGenCommitPercentImpl(percent);
}
@Override
public int getYoungGenCommitPercent() {
checkElasticHeapEnabled();
return getYoungGenCommitPercentImpl();
}
@Override
public void setUncommitIHOP(int percent) {
checkElasticHeapEnabled();
if (percent < 0 || percent > 100) {
throw new IllegalArgumentException("argument should be between 0 and 100");
}
setUncommitIHOPImpl(percent);
}
@Override
public int getUncommitIHOP() {
checkElasticHeapEnabled();
return getUncommitIHOPImpl();
}
@Override
public long getTotalYoungUncommittedBytes() {
checkElasticHeapEnabled();
return getTotalYoungUncommittedBytesImpl();
}
@Override
public void setSoftmxPercent(int percent) {
checkElasticHeapEnabled();
if (percent < 0 || percent > 100) {
throw new IllegalArgumentException("argument should be between 0 and 100");
}
setSoftmxPercentImpl(percent);
}
@Override
public int getSoftmxPercent() {
checkElasticHeapEnabled();
return getSoftmxPercentImpl();
}
@Override
public long getTotalUncommittedBytes() {
checkElasticHeapEnabled();
return getTotalUncommittedBytesImpl();
}
@Override
public ObjectName getObjectName() {
return Util.newObjectName(ELASTIC_HEAP_MXBEAN_NAME);
}
private static native int getEvaluationModeImpl();
private static native void setYoungGenCommitPercentImpl(int percent);
private static native int getYoungGenCommitPercentImpl();
private static native void setUncommitIHOPImpl(int percent);
private static native int getUncommitIHOPImpl();
private static native long getTotalYoungUncommittedBytesImpl();
private static native void setSoftmxPercentImpl(int percent);
private static native int getSoftmxPercentImpl();
private static native long getTotalUncommittedBytesImpl();
}
/*
* Copyright (c) 2019 Alibaba Group Holding Limited. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Alibaba designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.alibaba.management;
/**
* Enumeration of the evaluation mode of elastic heap in runtime
*/
public enum ElasticHeapEvaluationMode {
/**
* Inactive mode
*/
INACTIVE,
/**
* Periodic uncommit mode
*/
PERIODIC_UNCOMMIT,
/**
* Generation limit mode
*/
GENERATION_LIMIT,
/**
* Softmx mode
*/
SOFTMX
}
/*
* Copyright (c) 2019 Alibaba Group Holding Limited. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Alibaba designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.alibaba.management;
import java.lang.management.PlatformManagedObject;
import java.util.List;
/**
* The ElasticHeapMXBean interface provides APIs for manipulating memory commitment of heap
*/
public interface ElasticHeapMXBean extends PlatformManagedObject {
/**
* @return ElasticHeapEvaluationMode of elastic heap
* @throws UnsupportedOperationException if -XX:+G1ElasticHeap is not enabled
*/
public ElasticHeapEvaluationMode getEvaluationMode();
/**
* Set memory commit percent of young generation in heap
*
* @param percent commit percent of young generation to set
* @throws UnsupportedOperationException if -XX:+G1ElasticHeap is not enabled
* @throws IllegalStateException if commit percent cannot be set. Error can be gotten by Exception.getMessage()
* @throws IllegalArgumentException if percent is not 0 or between
* ElasticHeapMinYoungCommitPercent(VM option) and 100
*/
public void setYoungGenCommitPercent(int percent);
/**
* @return memory commit percent of young generation percentage in heap
* (toInt(YoungGenCommitPercent * 100))
* @throws UnsupportedOperationException if -XX:+G1ElasticHeap is not enabled
* @throws IllegalStateException if not in command control mode
*/
public int getYoungGenCommitPercent();
/**
* Set memory commit percent of young generation in heap
*
* @param percent percent of heap to set to trigger concurrent mark and do memory uncommitment
* @throws UnsupportedOperationException if -XX:+G1ElasticHeap is not enabled
* @throws IllegalStateException if IHOP percent cannot be set. Error can be gotten by Exception.getMessage()
* @throws IllegalArgumentException if percent is not between 0 and 100
*/
public void setUncommitIHOP(int percent);
/**
* @return percent of heap to set to trigger concurrent mark and do memory uncommitment
* @throws UnsupportedOperationException if -XX:+G1ElasticHeap is not enabled
* @throws IllegalStateException if not in command control mode
*/
public int getUncommitIHOP();
/**
* @return number of uncommited bytes of young generation in heap
* @throws UnsupportedOperationException if -XX:+G1ElasticHeap is not enabled
* @throws IllegalStateException if not in command control mode
*/
public long getTotalYoungUncommittedBytes();
/**
* Set memory commit percent of heap
*
* @param percent the percentage of Softmx in Xmx to set
* @throws UnsupportedOperationException if -XX:+G1ElasticHeap is not enabled
* @throws IllegalStateException if percent cannot be set. Error can be gotten by Exception.getMessage()
* @throws IllegalArgumentException if percent is between 0 and 100
*/
public void setSoftmxPercent(int percent);
/**
* @return softmx percent
* @throws UnsupportedOperationException if -XX:+G1ElasticHeap is not enabled
* @throws IllegalStateException if not in softmx mode
*/
public int getSoftmxPercent();
/**
* @return number of uncommited bytes of heap
* @throws UnsupportedOperationException if -XX:+G1ElasticHeap is not enabled
* @throws IllegalStateException if not in softmx mode
*/
public long getTotalUncommittedBytes();
}
......@@ -35,6 +35,7 @@ import java.util.Set;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import com.alibaba.management.ElasticHeapMXBean;
import com.sun.management.HotSpotDiagnosticMXBean;
import com.sun.management.UnixOperatingSystemMXBean;
import com.sun.management.VMOption;
......@@ -294,6 +295,19 @@ enum PlatformComponent {
}
return Collections.emptyList();
}
}),
/**
* Elastic Heap.
*/
ELASTIC_HEAP(
"com.alibaba.management.ElasticHeapMXBean",
"com.alibaba.management", "ElasticHeap", defaultKeyProperties(),
true,
new MXBeanFetcher<ElasticHeapMXBean>() {
public List<ElasticHeapMXBean> getMXBeans() {
return Collections.singletonList(ManagementFactoryHelper.getElasticHeapMXBean());
}
});
/**
......
......@@ -39,6 +39,8 @@ import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import com.alibaba.management.ElasticHeapMXBean;
import com.alibaba.jvm.gc.ElasticHeapMXBeanImpl;
import sun.util.logging.LoggingSupport;
import java.util.ArrayList;
......@@ -69,6 +71,7 @@ public class ManagementFactoryHelper {
private static CompilationImpl compileMBean = null;
private static OperatingSystemImpl osMBean = null;
private static FlightRecorderMXBeanImpl flightRecorderMBean = null;
private static ElasticHeapMXBeanImpl elasticHeapMXBean = null;
public static synchronized ClassLoadingMXBean getClassLoadingMXBean() {
if (classMBean == null) {
......@@ -119,6 +122,13 @@ public class ManagementFactoryHelper {
return flightRecorderMBean;
}
public static synchronized ElasticHeapMXBean getElasticHeapMXBean() {
if (elasticHeapMXBean == null) {
elasticHeapMXBean = new ElasticHeapMXBeanImpl();
}
return elasticHeapMXBean;
}
public static List<MemoryPoolMXBean> getMemoryPoolMXBeans() {
MemoryPoolMXBean[] pools = MemoryImpl.getMemoryPools();
List<MemoryPoolMXBean> list = new ArrayList<>(pools.length);
......
......@@ -339,6 +339,28 @@ JVM_CheckJWarmUpCompilationIsComplete(JNIEnv *env, jclass clz);
JNIEXPORT void JNICALL
JVM_NotifyJVMDeoptWarmUpMethods(JNIEnv* env, jclass clz);
/*
* com.alibaba.management.ElasticHeapMXBean
*/
JNIEXPORT jint JNICALL
JVM_ElasticHeapGetEvaluationMode(JNIEnv *env, jclass clazz);
JNIEXPORT void JNICALL
JVM_ElasticHeapSetYoungGenCommitPercent(JNIEnv *env, jclass clazz, jint percent);
JNIEXPORT jint JNICALL
JVM_ElasticHeapGetYoungGenCommitPercent(JNIEnv *env, jclass clazz);
JNIEXPORT void JNICALL
JVM_ElasticHeapSetUncommitIHOP(JNIEnv *env, jclass clazz, jint percent);
JNIEXPORT jint JNICALL
JVM_ElasticHeapGetUncommitIHOP(JNIEnv *env, jclass clazz);
JNIEXPORT jlong JNICALL
JVM_ElasticHeapGetTotalYoungUncommittedBytes(JNIEnv *env, jclass clazz);
JNIEXPORT void JNICALL
JVM_ElasticHeapSetSoftmxPercent(JNIEnv *env, jclass clazz, jint percent);
JNIEXPORT jint JNICALL
JVM_ElasticHeapGetSoftmxPercent(JNIEnv *env, jclass clazz);
JNIEXPORT jlong JNICALL
JVM_ElasticHeapGetTotalUncommittedBytes(JNIEnv *env, jclass clazz);
/*
* java.lang.reflect.Array
*/
......
/*
* Copyright (c) 2019 Alibaba Group Holding Limited. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Alibaba designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "jni.h"
#include "jvm.h"
#include "com_alibaba_jvm_gc_ElasticHeapMXBeanImpl.h"
#define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0]))
static JNINativeMethod methods[] = {
{"getEvaluationModeImpl", "()I", (void *)&JVM_ElasticHeapGetEvaluationMode},
{"setYoungGenCommitPercentImpl", "(I)V", (void *)&JVM_ElasticHeapSetYoungGenCommitPercent},
{"getYoungGenCommitPercentImpl", "()I", (void *)&JVM_ElasticHeapGetYoungGenCommitPercent},
{"setUncommitIHOPImpl", "(I)V", (void *)&JVM_ElasticHeapSetUncommitIHOP},
{"getUncommitIHOPImpl", "()I", (void *)&JVM_ElasticHeapGetUncommitIHOP},
{"getTotalYoungUncommittedBytesImpl", "()J", (void *)&JVM_ElasticHeapGetTotalYoungUncommittedBytes},
{"setSoftmxPercentImpl", "(I)V", (void *)&JVM_ElasticHeapSetSoftmxPercent},
{"getSoftmxPercentImpl", "()I", (void *)&JVM_ElasticHeapGetSoftmxPercent},
{"getTotalUncommittedBytesImpl", "()J", (void *)&JVM_ElasticHeapGetTotalUncommittedBytes},
};
JNIEXPORT void JNICALL
Java_com_alibaba_jvm_gc_ElasticHeapMXBeanImpl_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls, methods, ARRAY_LENGTH(methods));
}
/*
* Copyright (c) 2019 Alibaba Group Holding Limited. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Alibaba designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import com.alibaba.management.*;
import javax.management.*;
import javax.management.remote.*;
import java.lang.management.ManagementFactory;
import java.io.File;
import jdk.testlibrary.*;
import jdk.testlibrary.dcmd.*;
import static jdk.testlibrary.Asserts.assertTrue;
/* @test
* @summary test elastic-heap error code
* @library /lib/testlibrary
* @compile TestElasticHeapErrorCode.java
* @run main/othervm/timeout=100 TestElasticHeapErrorCode
*/
public class TestElasticHeapErrorCode {
public static void main(String[] args) throws Exception {
ProcessBuilder serverBuilder;
serverBuilder = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
"-Xmx1g", "-Xms1g",
"-Xmn100m", "-XX:G1HeapRegionSize=1m",
"-XX:ElasticHeapYGCIntervalMinMillis=500",
"-Dtest.jdk=" + System.getProperty("test.jdk"),
"-verbose:gc", "-XX:+PrintGCDetails", "-XX:+PrintGCTimeStamps",
Server.class.getName());
Process server = serverBuilder.start();
OutputAnalyzer output = new OutputAnalyzer(server);
System.out.println(output.getOutput());
output.shouldContain("-XX:+G1ElasticHeap is not enabled");
assertTrue(output.getExitValue() == 0);
serverBuilder = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
"-XX:+G1ElasticHeap",
"-Xmx1g", "-Xms1g",
"-Xmn100m", "-XX:G1HeapRegionSize=1m",
"-XX:ElasticHeapYGCIntervalMinMillis=500",
"-Dtest.jdk=" + System.getProperty("test.jdk"),
"-verbose:gc", "-XX:+PrintGCDetails", "-XX:+PrintGCTimeStamps",
Server.class.getName());
server = serverBuilder.start();
output = new OutputAnalyzer(server);
System.out.println(output.getOutput());
output.shouldContain("Error: percent should be");
output.shouldContain("Error: gc is too frequent");
output.shouldContain("Error: young_commit_percent should be");
output.shouldContain("Error: command fails because gc is too frequent");
assertTrue(output.getExitValue() == 0);
}
private static class Server {
public static void main(String[] args) throws Exception {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ElasticHeapMXBean elasticHeapMXBean = ManagementFactory.newPlatformMXBeanProxy(server,
"com.alibaba.management:type=ElasticHeap",
ElasticHeapMXBean.class);
byte[] arr = new byte[200*1024];
// Allocate 200k per 1ms, 200M per second
// so 2 GCs per second
for (int i = 0; i < 1000 * 5; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
try {
elasticHeapMXBean.setYoungGenCommitPercent(5);
} catch (Exception e) {
System.out.println("Error: "+ e.getMessage());
}
try {
elasticHeapMXBean.setYoungGenCommitPercent(50);
} catch (Exception e) {
System.out.println("Error: "+ e.getMessage());
}
PidJcmdExecutor je = new PidJcmdExecutor();
je.execute("GC.elastic_heap young_commit_percent=5");
je.execute("GC.elastic_heap young_commit_percent=50");
for (int i = 0; i < 1000 * 5; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
}
}
}
/*
* Copyright (c) 2019 Alibaba Group Holding Limited. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Alibaba designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import com.alibaba.management.*;
import javax.management.*;
import javax.management.remote.*;
import java.lang.management.ManagementFactory;
import java.io.File;
import jdk.testlibrary.*;
import jdk.testlibrary.dcmd.*;
import static jdk.testlibrary.Asserts.assertTrue;
/* @test
* @summary test elastic-heap error with multiple threads setting
* @library /lib/testlibrary
* @compile TestElasticHeapMTSetError.java
* @run main/othervm/timeout=100 TestElasticHeapMTSetError
*/
class ElasticHeapMTSetErrorSetter implements Runnable {
public void run() {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
try {
ElasticHeapMXBean elasticHeapMXBean = ManagementFactory.newPlatformMXBeanProxy(server,
"com.alibaba.management:type=ElasticHeap",
ElasticHeapMXBean.class);
elasticHeapMXBean.setYoungGenCommitPercent(50);
} catch (Exception e) {
System.out.println("Error: "+ e.getMessage());
}
}
}
public class TestElasticHeapMTSetError {
public static void main(String[] args) throws Exception {
ProcessBuilder serverBuilder;
serverBuilder = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
"-XX:+G1ElasticHeap",
"-Xmx1g", "-Xms1g",
"-Xmn100m", "-XX:G1HeapRegionSize=1m",
"-XX:ElasticHeapYGCIntervalMinMillis=50",
"-Dtest.jdk=" + System.getProperty("test.jdk"),
"-verbose:gc", "-XX:+PrintGCDetails", "-XX:+PrintGCTimeStamps",
Server.class.getName());
Process server = serverBuilder.start();
OutputAnalyzer output = new OutputAnalyzer(server);
System.out.println(output.getOutput());
output.shouldContain("last elastic-heap resize is still in progress");
output.shouldContain("Elastic Heap concurrent cycle ends");
assertTrue(output.getExitValue() == 0);
}
private static class Server {
public static void main(String[] args) throws Exception {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ElasticHeapMXBean elasticHeapMXBean = ManagementFactory.newPlatformMXBeanProxy(server,
"com.alibaba.management:type=ElasticHeap",
ElasticHeapMXBean.class);
byte[] arr = new byte[200*1024];
// Allocate 200k per 1ms, 200M per second
// so 2 GCs per second
for (int i = 0; i < 1000 * 5; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
ElasticHeapMTSetErrorSetter setter = new ElasticHeapMTSetErrorSetter();
Thread t1 = new Thread(setter, "t1");
Thread t2 = new Thread(setter, "t2");
Thread t3 = new Thread(setter, "t3");
Thread t4 = new Thread(setter, "t4");
Thread t5 = new Thread(setter, "t5");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
for (int i = 0; i < 1000 * 5; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
}
}
}
/*
* Copyright (c) 2019 Alibaba Group Holding Limited. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Alibaba designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import com.alibaba.management.*;
import javax.management.*;
import javax.management.remote.*;
import java.lang.management.ManagementFactory;
import java.io.File;
import java.util.*;
import jdk.testlibrary.*;
import static jdk.testlibrary.Asserts.assertTrue;
/* @test
* @summary test elastic-heap MX bean
* @library /lib/testlibrary
* @compile TestElasticHeapMXBean.java
* @run main/othervm/timeout=100 TestElasticHeapMXBean
*/
public class TestElasticHeapMXBean {
public static void main(String[] args) throws Exception {
ProcessBuilder serverBuilder;
if (System.getProperty("java.vm.version").toLowerCase().contains("debug")) {
serverBuilder = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
"-XX:+G1ElasticHeap", "-Xmx1000m", "-Xms1000m",
"-Xmn100m", "-XX:G1HeapRegionSize=1m",
"-XX:ElasticHeapYGCIntervalMinMillis=50",
"-verbose:gc", "-XX:+PrintGCDetails", "-XX:+PrintGCTimeStamps",
Server.class.getName());
Process server = serverBuilder.start();
OutputAnalyzer output = new OutputAnalyzer(server);
System.out.println(output.getOutput());
output.shouldContain("Set young percent 50: 50");
output.shouldContain("Set freed bytes 50M: 52428800");
output.shouldContain("Set young percent 100: 100");
output.shouldContain("Set freed bytes 0M: 0");
output.shouldContain("Set softmx percent 70: 70");
output.shouldContain("Set freed bytes 300M: 314572800");
output.shouldContain("Set softmx percent 50: 50");
output.shouldContain("Set freed bytes 500M: 524288000");
output.shouldContain("Evaluation mode: inactive");
assertTrue(output.getExitValue() == 0);
}
else {
// Release build uses JMX remote access
Random rand = new Random(25);
int i;
i = rand.nextInt(10000);
int port = 10000 + i;
serverBuilder = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
"-XX:+G1ElasticHeap", "-Xmx1000m", "-Xms1000m",
"-Xmn100m", "-XX:G1HeapRegionSize=1m",
"-Dcom.sun.management.jmxremote.port=" + port,
"-Dcom.sun.management.jmxremote.ssl=false",
"-Dcom.sun.management.jmxremote.authenticate=false",
"-XX:ElasticHeapYGCIntervalMinMillis=50",
"-verbose:gc", "-XX:+PrintGCDetails", "-XX:+PrintGCTimeStamps",
"-Xloggc:gc.log",
ServerJMX.class.getName());
Process server = serverBuilder.start();
Thread.sleep(5000);
ProcessBuilder clientBuilder;
clientBuilder = ProcessTools.createJavaProcessBuilder(Client.class.getName(), port + "");
OutputAnalyzer output = new OutputAnalyzer(clientBuilder.start());
OutputAnalyzer outputServer = new OutputAnalyzer(server);
System.out.println(outputServer.getOutput());
output.shouldContain("Set young percent 50: 50");
output.shouldContain("Set freed bytes 50M: 52428800");
output.shouldContain("Set young percent 100: 100");
output.shouldContain("Set freed bytes 0M: 0");
output.shouldContain("Set heap percent 70: 70");
output.shouldContain("Set freed bytes 300M: 314572800");
output.shouldContain("Set heap percent 50: 50");
output.shouldContain("Set freed bytes 500M: 524288000");
output.shouldContain("Evaluation mode: inactive");
assertTrue(output.getExitValue() == 0);
assertTrue(outputServer.getExitValue() == 0);
}
}
private static class Client {
public static void main(String[] args) {
try {
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + "127.0.0.1:" + args[0] + "/jmxrmi");
MBeanServerConnection connection = JMXConnectorFactory.connect(url, null).getMBeanServerConnection();
ElasticHeapMXBean elasticHeapMXBean = ManagementFactory.newPlatformMXBeanProxy(connection,
"com.alibaba.management:type=ElasticHeap",
ElasticHeapMXBean.class);
elasticHeapMXBean.setYoungGenCommitPercent(50);
System.out.println("Set young percent 50: " + elasticHeapMXBean.getYoungGenCommitPercent());
System.out.println("Set freed bytes 50M: " + elasticHeapMXBean.getTotalYoungUncommittedBytes());
Thread.sleep(3000);
elasticHeapMXBean.setYoungGenCommitPercent(100);
System.out.println("Set young percent 100: " + elasticHeapMXBean.getYoungGenCommitPercent());
System.out.println("Set freed bytes 0M: " + elasticHeapMXBean.getTotalYoungUncommittedBytes());
elasticHeapMXBean.setYoungGenCommitPercent(0);
Thread.sleep(3000);
elasticHeapMXBean.setSoftmxPercent(70);
Thread.sleep(3000);
System.out.println("Set heap percent 70: " + elasticHeapMXBean.getSoftmxPercent());
System.out.println("Set freed bytes 300M: " + elasticHeapMXBean.getTotalUncommittedBytes());
Thread.sleep(3000);
elasticHeapMXBean.setSoftmxPercent(50);
Thread.sleep(3000);
System.out.println("Set heap percent 50: " + elasticHeapMXBean.getSoftmxPercent());
System.out.println("Set freed bytes 500M: " + elasticHeapMXBean.getTotalUncommittedBytes());
Thread.sleep(3000);
elasticHeapMXBean.setSoftmxPercent(0);
Thread.sleep(3000);
System.out.println("Evaluation mode: " + (elasticHeapMXBean.getEvaluationMode() == ElasticHeapEvaluationMode.INACTIVE? "inactive" : "unexpected"));
} catch (Exception e) {
System.out.println("Error: "+ e.getMessage());
}
}
}
private static class ServerJMX {
public static void main(String[] args) throws Exception {
byte[] arr = new byte[200*1024];
// Allocate 200k per 1ms, 200M per second
// so 2 GCs per second
for (int i = 0; i < 1000 * 40; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
}
}
private static class Server {
public static void main(String[] args) throws Exception {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ElasticHeapMXBean elasticHeapMXBean = ManagementFactory.newPlatformMXBeanProxy(server,
"com.alibaba.management:type=ElasticHeap",
ElasticHeapMXBean.class);
byte[] arr = new byte[200*1024];
// Allocate 200k per 1ms, 200M per second
// so 2 GCs per second
for (int i = 0; i < 1000 * 3; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
elasticHeapMXBean.setYoungGenCommitPercent(50);
System.out.println("Set young percent 50: " + elasticHeapMXBean.getYoungGenCommitPercent());
System.out.println("Set freed bytes 50M: " + elasticHeapMXBean.getTotalYoungUncommittedBytes());
for (int i = 0; i < 1000 * 5; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
elasticHeapMXBean.setYoungGenCommitPercent(100);
System.out.println("Set young percent 100: " + elasticHeapMXBean.getYoungGenCommitPercent());
System.out.println("Set freed bytes 0M: " + elasticHeapMXBean.getTotalYoungUncommittedBytes());
for (int i = 0; i < 1000 * 5; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
elasticHeapMXBean.setYoungGenCommitPercent(0);
for (int i = 0; i < 1000 * 5; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
elasticHeapMXBean.setSoftmxPercent(70);
for (int i = 0; i < 1000 * 5; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
System.out.println("Set softmx percent 70: " + elasticHeapMXBean.getSoftmxPercent());
System.out.println("Set freed bytes 300M: " + elasticHeapMXBean.getTotalUncommittedBytes());
for (int i = 0; i < 1000 * 5; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
elasticHeapMXBean.setSoftmxPercent(50);
for (int i = 0; i < 1000 * 5; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
System.out.println("Set softmx percent 50: " + elasticHeapMXBean.getSoftmxPercent());
System.out.println("Set freed bytes 500M: " + elasticHeapMXBean.getTotalUncommittedBytes());
for (int i = 0; i < 1000 * 5; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
elasticHeapMXBean.setSoftmxPercent(0);
for (int i = 0; i < 1000 * 5; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
System.out.println("Evaluation mode: " + (elasticHeapMXBean.getEvaluationMode() == ElasticHeapEvaluationMode.INACTIVE? "inactive" : "unexpected"));
}
}
}
/*
* Copyright (c) 2019 Alibaba Group Holding Limited. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Alibaba designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import com.alibaba.management.*;
import javax.management.*;
import javax.management.remote.*;
import java.lang.management.ManagementFactory;
import java.io.File;
import jdk.testlibrary.*;
import static jdk.testlibrary.Asserts.*;
/* @test
* @summary test elastic-heap MX bean exception
* @library /lib/testlibrary
* @compile TestElasticHeapMXBeanException.java
* @run main/othervm/timeout=100 TestElasticHeapMXBeanException
*/
public class TestElasticHeapMXBeanException {
public static void main(String[] args) throws Exception {
ProcessBuilder serverBuilder;
Process server;
OutputAnalyzer output;
serverBuilder = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
"-Xmx1g", "-Xms1g",
"-Xmn100m", "-XX:G1HeapRegionSize=1m",
"-XX:ElasticHeapYGCIntervalMinMillis=50",
"-verbose:gc", "-XX:+PrintGCDetails", "-XX:+PrintGCTimeStamps",
ServerNotEnabled.class.getName());
server = serverBuilder.start();
output = new OutputAnalyzer(server);
System.out.println(output.getOutput());
assertTrue(output.getExitValue() == 0);
serverBuilder = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
"-Xmx1g", "-Xms1g",
"-Xmn100m", "-XX:G1HeapRegionSize=1m",
"-XX:+G1ElasticHeap", "-XX:+ElasticHeapPeriodicUncommit",
"-XX:ElasticHeapYGCIntervalMinMillis=50",
"-verbose:gc", "-XX:+PrintGCDetails", "-XX:+PrintGCTimeStamps",
ServerIncorrectMode.class.getName());
server = serverBuilder.start();
output = new OutputAnalyzer(server);
System.out.println(output.getOutput());
assertTrue(output.getExitValue() == 0);
serverBuilder = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
"-Xmx1g", "-Xms1g",
"-Xmn100m", "-XX:G1HeapRegionSize=1m",
"-XX:+G1ElasticHeap",
"-XX:ElasticHeapYGCIntervalMinMillis=50",
"-verbose:gc", "-XX:+PrintGCDetails", "-XX:+PrintGCTimeStamps",
ServerIncorrectMode2.class.getName());
server = serverBuilder.start();
output = new OutputAnalyzer(server);
System.out.println(output.getOutput());
assertTrue(output.getExitValue() == 0);
}
private static class ServerNotEnabled {
public static void main(String[] args) throws Exception {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ElasticHeapMXBean elasticHeapMXBean = ManagementFactory.newPlatformMXBeanProxy(server,
"com.alibaba.management:type=ElasticHeap",
ElasticHeapMXBean.class);
byte[] arr = new byte[200*1024];
// Allocate 200k per 1ms, 200M per second
// so 2 GCs per second
for (int i = 0; i < 1000 * 3; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
int percent = 0;
long bytes = 0;
ElasticHeapEvaluationMode mode;
try {
mode = elasticHeapMXBean.getEvaluationMode();
fail();
} catch (Exception e) {
if (!e.getMessage().contains("-XX:+G1ElasticHeap is not enabled")) {
fail();
}
}
try {
elasticHeapMXBean.setYoungGenCommitPercent(50);
fail();
} catch (Exception e) {
if (!e.getMessage().contains("-XX:+G1ElasticHeap is not enabled")) {
fail();
}
}
try {
percent = elasticHeapMXBean.getYoungGenCommitPercent();
fail();
} catch (Exception e) {
if (!e.getMessage().contains("-XX:+G1ElasticHeap is not enabled")) {
fail();
}
}
try {
elasticHeapMXBean.setUncommitIHOP(50);
fail();
} catch (Exception e) {
if (!e.getMessage().contains("-XX:+G1ElasticHeap is not enabled")) {
fail();
}
}
try {
percent = elasticHeapMXBean.getUncommitIHOP();
fail();
} catch (Exception e) {
if (!e.getMessage().contains("-XX:+G1ElasticHeap is not enabled")) {
fail();
}
}
try {
bytes = elasticHeapMXBean.getTotalYoungUncommittedBytes();
fail();
} catch (Exception e) {
if (!e.getMessage().contains("-XX:+G1ElasticHeap is not enabled")) {
fail();
}
}
try {
elasticHeapMXBean.setSoftmxPercent(50);
fail();
} catch (Exception e) {
if (!e.getMessage().contains("-XX:+G1ElasticHeap is not enabled")) {
fail();
}
}
try {
percent = elasticHeapMXBean.getSoftmxPercent();
fail();
} catch (Exception e) {
if (!e.getMessage().contains("-XX:+G1ElasticHeap is not enabled")) {
fail();
}
}
try {
bytes = elasticHeapMXBean.getTotalUncommittedBytes();
fail();
} catch (Exception e) {
if (!e.getMessage().contains("-XX:+G1ElasticHeap is not enabled")) {
fail();
}
}
}
}
private static class ServerIncorrectMode {
public static void main(String[] args) throws Exception {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ElasticHeapMXBean elasticHeapMXBean = ManagementFactory.newPlatformMXBeanProxy(server,
"com.alibaba.management:type=ElasticHeap",
ElasticHeapMXBean.class);
byte[] arr = new byte[200*1024];
// Allocate 200k per 1ms, 200M per second
// so 2 GCs per second
for (int i = 0; i < 1000 * 3; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
int percent = 0;
long bytes = 0;
ElasticHeapEvaluationMode mode;
try {
elasticHeapMXBean.setYoungGenCommitPercent(50);
fail();
} catch (Exception e) {
if (!e.getMessage().contains("not in correct mode")) {
fail();
}
}
try {
elasticHeapMXBean.setUncommitIHOP(50);
fail();
} catch (Exception e) {
if (!e.getMessage().contains("not in correct mode")) {
fail();
}
}
try {
elasticHeapMXBean.setSoftmxPercent(50);
fail();
} catch (Exception e) {
if (!e.getMessage().contains("not in correct mode")) {
fail();
}
}
}
}
private static class ServerIncorrectMode2 {
public static void main(String[] args) throws Exception {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ElasticHeapMXBean elasticHeapMXBean = ManagementFactory.newPlatformMXBeanProxy(server,
"com.alibaba.management:type=ElasticHeap",
ElasticHeapMXBean.class);
byte[] arr = new byte[200*1024];
// Allocate 200k per 1ms, 200M per second
// so 2 GCs per second
for (int i = 0; i < 1000 * 3; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
int percent = 0;
long bytes = 0;
ElasticHeapEvaluationMode mode;
try {
elasticHeapMXBean.setYoungGenCommitPercent(50);
} catch (Exception e) {
fail();
}
try {
percent = elasticHeapMXBean.getSoftmxPercent();
} catch (Exception e) {
fail();
}
try {
elasticHeapMXBean.setSoftmxPercent(50);
fail();
} catch (Exception e) {
if (!e.getMessage().contains("not in correct mode")) {
fail();
}
}
try {
elasticHeapMXBean.setUncommitIHOP(50);
} catch (Exception e) {
fail();
}
try {
elasticHeapMXBean.setYoungGenCommitPercent(0);
} catch (Exception e) {
fail();
}
try {
elasticHeapMXBean.setSoftmxPercent(50);
fail();
} catch (Exception e) {
if (!e.getMessage().contains("not in correct mode")) {
fail();
}
}
try {
elasticHeapMXBean.setUncommitIHOP(0);
} catch (Exception e) {
fail();
}
for (int i = 0; i < 1000 * 3; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
try {
elasticHeapMXBean.setSoftmxPercent(50);
} catch (Exception e) {
fail();
}
for (int i = 0; i < 1000 * 3; i++) {
arr = new byte[200*1024];
Thread.sleep(1);
}
try {
percent = elasticHeapMXBean.getSoftmxPercent();
} catch (Exception e) {
fail();
}
assertTrue(percent == 50);
try {
elasticHeapMXBean.setYoungGenCommitPercent(60);
fail();
} catch (Exception e) {
if (!e.getMessage().contains("not in correct mode")) {
fail();
}
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册