"...main/java/com/git@ustchcs.com:gujinli/compute-service.git" did not exist on "70f7d18d9df5ec79dc80cb1b648a83ea38c1addd"
Commit 45ea67e5 authored by gao wj's avatar gao wj
Browse files

test-java2

parents
/*
* Copyright (c) 1999, Oracle and/or its affiliates. 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. Oracle 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.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_JAWT_MD_H_
#define _JAVASOFT_JAWT_MD_H_
#include <windows.h>
#include "jawt.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Win32-specific declarations for AWT native interface.
* See notes in jawt.h for an example of use.
*/
typedef struct jawt_Win32DrawingSurfaceInfo {
/* Native window, DDB, or DIB handle */
union {
HWND hwnd;
HBITMAP hbitmap;
void* pbits;
};
/*
* This HDC should always be used instead of the HDC returned from
* BeginPaint() or any calls to GetDC().
*/
HDC hdc;
HPALETTE hpalette;
} JAWT_Win32DrawingSurfaceInfo;
#ifdef __cplusplus
}
#endif
#endif /* !_JAVASOFT_JAWT_MD_H_ */
/*
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. 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. Oracle 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.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_
#ifndef JNIEXPORT
#define JNIEXPORT __declspec(dllexport)
#endif
#define JNIIMPORT __declspec(dllimport)
#define JNICALL __stdcall
// 'long' is always 32 bit on windows so this matches what jdk expects
typedef long jint;
typedef __int64 jlong;
typedef signed char jbyte;
#endif /* !_JAVASOFT_JNI_MD_H_ */
#include <iostream>
#include <jni.h>
#include <jni_md.h>
#include <jvmti.h>
#include "arthas_VmTool.h" // under target/native/javah/
static jvmtiEnv *jvmti;
static jlong tagCounter = 0;
struct LimitCounter {
jint currentCounter;
jint limitValue;
void init(jint limit) {
currentCounter = 0;
limitValue = limit;
}
void countDown() {
currentCounter++;
}
bool allow() {
if (limitValue < 0) {
return true;
}
return limitValue > currentCounter;
}
};
// 每次 IterateOverInstancesOfClass 调用前需要先 init
static LimitCounter limitCounter = {0, 0};
extern "C"
int init_agent(JavaVM *vm, void *reserved) {
jint rc;
/* Get JVMTI environment */
rc = vm->GetEnv((void **)&jvmti, JVMTI_VERSION_1_2);
if (rc != JNI_OK) {
fprintf(stderr, "ERROR: arthas vmtool Unable to create jvmtiEnv, GetEnv failed, error=%d\n", rc);
return -1;
}
jvmtiCapabilities capabilities = {0};
capabilities.can_tag_objects = 1;
jvmtiError error = jvmti->AddCapabilities(&capabilities);
if (error) {
fprintf(stderr, "ERROR: arthas vmtool JVMTI AddCapabilities failed!%u\n", error);
return JNI_FALSE;
}
return JNI_OK;
}
extern "C" JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *options, void *reserved) {
return init_agent(vm, reserved);
}
extern "C" JNIEXPORT jint JNICALL
Agent_OnAttach(JavaVM* vm, char* options, void* reserved) {
return init_agent(vm, reserved);
}
extern "C" JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM* vm, void* reserved) {
init_agent(vm, reserved);
return JNI_VERSION_1_6;
}
extern "C"
JNIEXPORT void JNICALL
Java_arthas_VmTool_forceGc0(JNIEnv *env, jclass thisClass) {
jvmti->ForceGarbageCollection();
}
extern "C"
jlong getTag() {
return ++tagCounter;
}
extern "C"
jvmtiIterationControl JNICALL
HeapObjectCallback(jlong class_tag, jlong size, jlong *tag_ptr, void *user_data) {
jlong *data = static_cast<jlong *>(user_data);
*tag_ptr = *data;
limitCounter.countDown();
if (limitCounter.allow()) {
return JVMTI_ITERATION_CONTINUE;
}else {
return JVMTI_ITERATION_ABORT;
}
}
extern "C"
JNIEXPORT jobjectArray JNICALL
Java_arthas_VmTool_getInstances0(JNIEnv *env, jclass thisClass, jclass klass, jint limit) {
jlong tag = getTag();
limitCounter.init(limit);
jvmtiError error = jvmti->IterateOverInstancesOfClass(klass, JVMTI_HEAP_OBJECT_EITHER,
HeapObjectCallback, &tag);
if (error) {
printf("ERROR: JVMTI IterateOverInstancesOfClass failed!%u\n", error);
return NULL;
}
jint count = 0;
jobject *instances;
error = jvmti->GetObjectsWithTags(1, &tag, &count, &instances, NULL);
if (error) {
printf("ERROR: JVMTI GetObjectsWithTags failed!%u\n", error);
return NULL;
}
jobjectArray array = env->NewObjectArray(count, klass, NULL);
//添加元素到数组
for (int i = 0; i < count; i++) {
env->SetObjectArrayElement(array, i, instances[i]);
}
jvmti->Deallocate(reinterpret_cast<unsigned char *>(instances));
return array;
}
extern "C"
JNIEXPORT jlong JNICALL
Java_arthas_VmTool_sumInstanceSize0(JNIEnv *env, jclass thisClass, jclass klass) {
jlong tag = getTag();
limitCounter.init(-1);
jvmtiError error = jvmti->IterateOverInstancesOfClass(klass, JVMTI_HEAP_OBJECT_EITHER,
HeapObjectCallback, &tag);
if (error) {
printf("ERROR: JVMTI IterateOverInstancesOfClass failed!%u\n", error);
return -1;
}
jint count = 0;
jobject *instances;
error = jvmti->GetObjectsWithTags(1, &tag, &count, &instances, NULL);
if (error) {
printf("ERROR: JVMTI GetObjectsWithTags failed!%u\n", error);
return -1;
}
jlong sum = 0;
for (int i = 0; i < count; i++) {
jlong size = 0;
jvmti->GetObjectSize(instances[i], &size);
sum = sum + size;
}
jvmti->Deallocate(reinterpret_cast<unsigned char *>(instances));
return sum;
}
extern "C"
JNIEXPORT jlong JNICALL Java_arthas_VmTool_getInstanceSize0
(JNIEnv *env, jclass thisClass, jobject instance) {
jlong size = -1;
jvmtiError error = jvmti->GetObjectSize(instance, &size);
if (error) {
printf("ERROR: JVMTI GetObjectSize failed!%u\n", error);
}
return size;
}
extern "C"
JNIEXPORT jlong JNICALL
Java_arthas_VmTool_countInstances0(JNIEnv *env, jclass thisClass, jclass klass) {
jlong tag = getTag();
limitCounter.init(-1);
jvmtiError error = jvmti->IterateOverInstancesOfClass(klass, JVMTI_HEAP_OBJECT_EITHER,
HeapObjectCallback, &tag);
if (error) {
printf("ERROR: JVMTI IterateOverInstancesOfClass failed!%u\n", error);
return -1;
}
jint count = 0;
error = jvmti->GetObjectsWithTags(1, &tag, &count, NULL, NULL);
if (error) {
printf("ERROR: JVMTI GetObjectsWithTags failed!%u\n", error);
return -1;
}
return count;
}
extern "C"
JNIEXPORT jobjectArray JNICALL Java_arthas_VmTool_getAllLoadedClasses0
(JNIEnv *env, jclass thisClass, jclass kclass) {
jclass *classes;
jint count = 0;
jvmtiError error = jvmti->GetLoadedClasses(&count, &classes);
if (error) {
printf("ERROR: JVMTI GetLoadedClasses failed!\n");
return NULL;
}
jobjectArray array = env->NewObjectArray(count, kclass, NULL);
//添加元素到数组
for (int i = 0; i < count; i++) {
env->SetObjectArrayElement(array, i, classes[i]);
}
jvmti->Deallocate(reinterpret_cast<unsigned char *>(classes));
return array;
}
\ No newline at end of file
package arthas;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicLong;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import com.taobao.arthas.common.VmToolUtils;
/**
* 以下本地测试的jvm参数均为:-Xms128m -Xmx128m
*/
public class VmToolTest {
private VmTool initVmTool() {
File path = new File(VmTool.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getParentFile();
String libPath = new File(path, VmToolUtils.detectLibName()).getAbsolutePath();
return VmTool.getInstance(libPath);
}
/**
* macbook上运行结果如下
* allLoadedClasses->1050
* arthas.VmTool@5bb21b69 arthas.VmTool@6b9651f3
* before instances->[arthas.VmTool@5bb21b69, arthas.VmTool@6b9651f3]
* size->16
* count->2
* sum size->32
* null null
* after instances->[]
*/
@Test
public void testIsSnapshot() {
try {
VmTool vmtool = initVmTool();
//调用native方法,获取已加载的类,不包括小类型(如int)
Class<?>[] allLoadedClasses = vmtool.getAllLoadedClasses();
System.out.println("allLoadedClasses->" + allLoadedClasses.length);
//通过下面的例子,可以看到getInstances(Class<T> klass)拿到的是当前存活的所有对象
WeakReference<VmToolTest> weakReference1 = new WeakReference<VmToolTest>(new VmToolTest());
WeakReference<VmToolTest> weakReference2 = new WeakReference<VmToolTest>(new VmToolTest());
System.out.println(weakReference1.get() + " " + weakReference2.get());
VmTool[] beforeInstances = vmtool.getInstances(VmTool.class);
System.out.println("before instances->" + beforeInstances);
System.out.println("size->" + vmtool.getInstanceSize(weakReference1.get()));
System.out.println("count->" + vmtool.countInstances(VmTool.class));
System.out.println("sum size->" + vmtool.sumInstanceSize(VmTool.class));
beforeInstances = null;
vmtool.forceGc();
Thread.sleep(100);
System.out.println(weakReference1.get() + " " + weakReference2.get());
VmTool[] afterInstances = vmtool.getInstances(VmTool.class);
System.out.println("after instances->" + afterInstances);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testGetInstancesMemoryLeak() {
//这里睡20s是为了方便用jprofiler连接上进程
// try {
// Thread.sleep(20000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
VmTool vmtool = initVmTool();
final AtomicLong totalTime = new AtomicLong();
//本地测试请改成200000
for (int i = 1; i <= 2; i++) {
long start = System.currentTimeMillis();
WeakReference<Object[]> reference = new WeakReference<Object[]>(vmtool.getInstances(Object.class));
Object[] instances = reference.get();
long cost = System.currentTimeMillis() - start;
totalTime.addAndGet(cost);
System.out.println(i + " instance size:" + (instances == null ? 0 : instances.length) + ", cost " + cost + "ms avgCost " + totalTime.doubleValue() / i + "ms");
instances = null;
vmtool.forceGc();
}
}
@Test
public void testSumInstancesMemoryLeak() {
//这里睡20s是为了方便用jprofiler连接上进程
// try {
// Thread.sleep(20000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
VmTool vmtool = initVmTool();
final AtomicLong totalTime = new AtomicLong();
//本地测试请改成200000
for (int i = 1; i <= 2; i++) {
long start = System.currentTimeMillis();
long sum = vmtool.sumInstanceSize(Object.class);
long cost = System.currentTimeMillis() - start;
totalTime.addAndGet(cost);
System.out.println(i + " sum:" + sum + ", cost " + cost + "ms avgCost " + totalTime.doubleValue() / i + "ms");
}
}
@Test
public void testCountInstancesMemoryLeak() {
//这里睡20s是为了方便用jprofiler连接上进程
// try {
// Thread.sleep(20000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
VmTool vmtool = initVmTool();
final AtomicLong totalTime = new AtomicLong();
//本地测试请改成200000
for (int i = 1; i <= 2; i++) {
long start = System.currentTimeMillis();
long count = vmtool.countInstances(Object.class);
long cost = System.currentTimeMillis() - start;
totalTime.addAndGet(cost);
System.out.println(i + " count:" + count + ", cost " + cost + "ms avgCost " + totalTime.doubleValue() / i + "ms");
}
}
@Test
public void testGetAllLoadedClassesMemoryLeak() {
//这里睡20s是为了方便用jprofiler连接上进程
// try {
// Thread.sleep(20000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
VmTool vmtool = initVmTool();
final AtomicLong totalTime = new AtomicLong();
//本地测试请改成200000
for (int i = 1; i <= 2; i++) {
long start = System.currentTimeMillis();
Class<?>[] allLoadedClasses = vmtool.getAllLoadedClasses();
long cost = System.currentTimeMillis() - start;
totalTime.addAndGet(cost);
System.out.println(i + " class size:" + allLoadedClasses.length + ", cost " + cost + "ms avgCost " + totalTime.doubleValue() / i + "ms");
allLoadedClasses = null;
}
}
class LimitTest {
}
@Test
public void test_getInstances_lmiit() {
VmTool vmtool = initVmTool();
ArrayList<LimitTest> list = new ArrayList<LimitTest>();
for (int i = 0; i < 10; ++i) {
list.add(new LimitTest());
}
LimitTest[] instances = vmtool.getInstances(LimitTest.class, 5);
Assertions.assertThat(instances).hasSize(5);
LimitTest[] instances2 = vmtool.getInstances(LimitTest.class, -1);
Assertions.assertThat(instances2).hasSize(10);
LimitTest[] instances3 = vmtool.getInstances(LimitTest.class, 1);
Assertions.assertThat(instances3).hasSize(1);
}
interface III {
}
class AAA implements III {
}
@Test
public void test_getInstances_interface() {
AAA aaa = new AAA();
VmTool vmtool = initVmTool();
III[] interfaceInstances = vmtool.getInstances(III.class);
Assertions.assertThat(interfaceInstances.length).isEqualTo(1);
AAA[] ObjectInstances = vmtool.getInstances(AAA.class);
Assertions.assertThat(ObjectInstances.length).isEqualTo(1);
Assertions.assertThat(interfaceInstances[0]).isEqualTo(ObjectInstances[0]);
}
}
#!/bin/bash
function build() {
local -a COMMITTED_FILES
COMMITTED_FILES=$(git diff --name-only --diff-filter=DCM $CI_COMMIT_SHA origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME)
if [ -z "$COMMITTED_FILES" ]; then
return
fi
local -a check_files
for dir in $COMMITTED_FILES; do
if [[ $dir =~ ${JAVA_MAIN_SOURCE} ]]; then
#如果不是 则跳过剩下的步骤
check_files+=("$REPOSITORY_FULL_PATH/"${dir})
fi
done
if [ -z "$check_files" ]; then
return
fi
S=$(IFS=' '; echo "${check_files[*]}")
echo $S
}
build "$@"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment