Преглед на файлове

新增Class的加载缓存,解决频繁加载Class会使jvm的方法区空间不足导致OOM的问题;

xuxueli преди 6 години
родител
ревизия
e6483c4b26

+ 2 - 1
doc/XXL-JOB官方文档.md Целия файл

@@ -1425,7 +1425,8 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
1425 1425
 - 11、执行器回调日志落盘方案复用RPC序列化方案,并移除Jackson依赖;
1426 1426
 - 12、任务支持更换绑定执行器,方便任务分组转移和管理;
1427 1427
 - 13、执行器热部署时JobHandler重新初始化,修复由此导致的 "jobhandler naming conflicts." 问题;
1428
-- 14、[迭代中]任务线程隔离:
1428
+- 14、新增Class的加载缓存,解决频繁加载Class会使jvm的方法区空间不足导致OOM的问题;
1429
+- 15、[迭代中]任务线程隔离:
1429 1430
     - 执行器测异步响应,不存在阻塞不需要隔离;
1430 1431
     - 调度中心共用单一调度线程池,可能导致调度阻塞需要线程隔离;调度线程池拆分为Fast/Slow两个,针对调度较慢的执行器地址请求,降级使用Slow线程池;考虑是否可以任务级隔离线程池;
1431 1432
 

+ 1 - 1
xxl-job-core/src/main/java/com/xxl/job/core/biz/impl/ExecutorBizImpl.java Целия файл

@@ -113,7 +113,7 @@ public class ExecutorBizImpl implements ExecutorBiz {
113 113
             // valid handler
114 114
             if (jobHandler == null) {
115 115
                 try {
116
-                    IJobHandler originJobHandler = GlueFactory.getInstance().loadNewInstance(triggerParam.getJobId(), triggerParam.getGlueSource());
116
+                    IJobHandler originJobHandler = GlueFactory.getInstance().loadNewInstance(triggerParam.getGlueSource());
117 117
                     jobHandler = new GlueJobHandler(originJobHandler, triggerParam.getGlueUpdatetime());
118 118
                 } catch (Exception e) {
119 119
                     logger.error(e.getMessage(), e);

+ 19 - 29
xxl-job-core/src/main/java/com/xxl/job/core/glue/GlueFactory.java Целия файл

@@ -33,9 +33,7 @@ public class GlueFactory {
33 33
 	 * groovy class loader
34 34
 	 */
35 35
 	private GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
36
-
37
-	private static final ConcurrentHashMap<String, Class<?>> CLASS_CACHE = new ConcurrentHashMap<>();
38
-	private static final ConcurrentHashMap<Long, String> JOBID_MD5KEY_CACHE = new ConcurrentHashMap<>();
36
+	private ConcurrentHashMap<String, Class<?>> CLASS_CACHE = new ConcurrentHashMap<>();
39 37
 
40 38
 	/**
41 39
 	 * load new instance, prototype
@@ -44,9 +42,9 @@ public class GlueFactory {
44 42
 	 * @return
45 43
 	 * @throws Exception
46 44
 	 */
47
-	public IJobHandler loadNewInstance(long jobId, String codeSource) throws Exception{
45
+	public IJobHandler loadNewInstance(String codeSource) throws Exception{
48 46
 		if (codeSource!=null && codeSource.trim().length()>0) {
49
-			Class<?> clazz = getCodeSourceClass(jobId, codeSource);
47
+			Class<?> clazz = getCodeSourceClass(codeSource);
50 48
 			if (clazz != null) {
51 49
 				Object instance = clazz.newInstance();
52 50
 				if (instance!=null) {
@@ -62,38 +60,30 @@ public class GlueFactory {
62 60
 		}
63 61
 		throw new IllegalArgumentException(">>>>>>>>>>> xxl-glue, loadNewInstance error, instance is null");
64 62
 	}
65
-
66
-	/**
67
-	 * inject service of bean field
68
-	 *
69
-	 * @param instance
70
-	 */
71
-	public void injectService(Object instance) {
72
-		// do something
73
-	}
74
-
75
-	private Class<?> getCodeSourceClass(long jobId, String codeSource){
63
+	private Class<?> getCodeSourceClass(String codeSource){
76 64
 		try {
77
-			MessageDigest md = MessageDigest.getInstance("MD5");
78
-			byte[] md5 = md.digest(codeSource.getBytes());
79
-			BigInteger no = new BigInteger(1, md5);
80
-			String md5Str = no.toString(16);
65
+			// md5
66
+			byte[] md5 = MessageDigest.getInstance("MD5").digest(codeSource.getBytes());
67
+			String md5Str = new BigInteger(1, md5).toString(16);
68
+
81 69
 			Class<?> clazz = CLASS_CACHE.get(md5Str);
82 70
 			if(clazz == null){
83 71
 				clazz = groovyClassLoader.parseClass(codeSource);
84
-				Class<?> preClazz = CLASS_CACHE.putIfAbsent(md5Str, clazz);
85
-
86
-				// 如果代碼有變化則刪除之前class緩存
87
-				if(preClazz == null){
88
-					String preMd5 = JOBID_MD5KEY_CACHE.put(jobId, md5Str);
89
-					if(preMd5 != null){
90
-						CLASS_CACHE.remove(preMd5);
91
-					}
92
-				}
72
+				CLASS_CACHE.putIfAbsent(md5Str, clazz);
93 73
 			}
94 74
 			return clazz;
95 75
 		} catch (Exception e) {
96 76
 			return groovyClassLoader.parseClass(codeSource);
97 77
 		}
98 78
 	}
79
+
80
+	/**
81
+	 * inject service of bean field
82
+	 *
83
+	 * @param instance
84
+	 */
85
+	public void injectService(Object instance) {
86
+		// do something
87
+	}
88
+
99 89
 }