网站开发用python吗,常用的网页开发工具有哪些,郑州做网站最好的公司,成都网站建设市场环境与背景
在java程序中通过GroovyScriptEvaluator执行器创建脚本Script对象调用Groovy脚本语言来完成某些功能, ,会通过AppClassLoader或者GroovyClassLoader去生产一个随机的名称的Groovy的Script类对象,导致元数据,产生的class类会被AppClassLoader或者GroovyClassLoader内…环境与背景
在java程序中通过GroovyScriptEvaluator执行器创建脚本Script对象调用Groovy脚本语言来完成某些功能, ,会通过AppClassLoader或者GroovyClassLoader去生产一个随机的名称的Groovy的Script类对象,导致元数据,产生的class类会被AppClassLoader或者GroovyClassLoader内部对应的Map所引用,导致不不能满足被垃圾回收的条件, 在执行脚本期间,得到了 Out of Metaspace出错 jdk8, groovy 2.4.6版本 dependencygroupIdorg.codehaus.groovy/groupIdartifactIdgroovy-all/artifactIdversion2.4.6/version/dependency执行脚本方式 1 Spring GroovyScriptEvaluator执行器 2.ScriptEngineManager 基于JDK的SPI方式提供的执行脚本引擎 3.基于GroovyShell 问题复现方式
GroovyScriptEngineImpl se;while (true)
{se new GroovyScriptEngineImpl(new GroovyClassLoader());CompiledScript script se.compile(println(\hello\));script.eval(se.createBindings());
}或者 private static GroovyScriptEvaluator evaluator new GroovyScriptEvaluator();public static Object evaluateScript(String script, MapString, Object context) {ScriptSource scriptSource new StaticScriptSource(script);return evaluator.evaluate(scriptSource, context);}public static void main(String[] args) {while (true) {evaluateScript(12, Maps.newHashMap());}}
JVM调优复现参数 -Xms200m -Xmx200m -Xss1m -XX:MetaspaceSize40m -XX:MaxMetaspaceSize40m -XX:PrintGCDetails -XX:PrintGCDateStamps -XX:PrintTenuringDistribution -XX:PrintHeapAtGC -XX:PrintGCApplicationStoppedTime -Xloggc:C:\Users\admin\Desktop\GC\gc-%t.log -XX:TraceClassLoading -XX:TraceClassUnloading -XX:UseGCLogFileRotation -XX:NumberOfGCLogFiles10 -XX:GCLogFileSize50M -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPathC:\Users\admin\Desktop\GC\memory.log 类加载机制-双亲委派
Groovy的ClassLoader体系 Bootstrap ClassLoader ↑ sun.misc.Launcher.ExtClassLoader // 即Extension ClassLoader ↑ sun.misc.Launcher.AppClassLoader // 即System ClassLoader ↑ org.codehaus.groovy.tools.RootLoader // 以下为User Custom ClassLoader ↑ groovy.lang.GroovyClassLoader ↑ groovy.lang.GroovyClassLoader.InnerLoader 异常现象
groovy 2.4.6 版本
解决思路: 1. 更换版本groovy2.4.8以及以上版本,则会回收Script类,可以解决问题,但是会存在性能问题 解决思路2: 升级jdk版本, 升级jdk版本11, 尝试解决类不会回收的问题
groovy 2.4.6 版本 出现问题 Exception in thread main java.lang.OutOfMemoryError: Metaspace
排查Metaspace方式
1. 通过jps命令,查看java进程pid 2. 通过jinfo 命令查看额外的java参数配置信息 3. 通过jmap用来查看内存信息实例个数以及占用内存大小 num序号instances实例数量bytes占用空间大小class name类名称[C is a char[][S is a short[][I is a int[][B is a byte[][[I is a int[][]
4. 通过jstat 命令查看堆内存各部分的使用量以及加载类的数量
评估程序内存使用及GC压力整体情况 S0C第一个幸存区的大小单位KB S1C第二个幸存区的大小 S0U第一个幸存区的使用大小 S1U第二个幸存区的使用大小 EC伊甸园区的大小 EU伊甸园区的使用大小 OC老年代大小 OU老年代使用大小 MC方法区大小(元空间) MU方法区使用大小 CCSC:压缩类空间大小 CCSU:压缩类空间使用大小 YGC年轻代垃圾回收次数 YGCT年轻代垃圾回收消耗时间单位s FGC老年代垃圾回收次数 FGCT老年代垃圾回收消耗时间单位s GCT垃圾回收消耗总时间单位s 堆内存统计 NGCMN新生代最小容量 NGCMX新生代最大容量 NGC当前新生代容量 S0C第一个幸存区大小 S1C第二个幸存区的大小 EC伊甸园区的大小 OGCMN老年代最小容量 OGCMX老年代最大容量 OGC当前老年代大小 OC:当前老年代大小 MCMN:最小元数据容量 MCMX最大元数据容量 MC当前元数据空间大小 CCSMN最小压缩类空间大小 CCSMX最大压缩类空间大小 CCSC当前压缩类空间大小 YGC年轻代gc次数 FGC老年代GC次数 jconsole 查看堆栈元数据等信息 分析内存溢出信息 jvisualvm
-XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath./ 路径 通过参数, 导入dump文件
查看相应的堆栈信息, 以及方法入栈/出栈等信息, 系统属性 显示线程 等确定代码异常位置查看类信息, 找出类创建数量多的类, 是否有自己写的相关类信息,进行代码定位
代码解决方案
升级groovy版本为2.4.8或以上版本 1. java SPI提供的接口方式
Slf4j
public class GroovyScriptUtil {public GroovyScriptUtil() {}private static final String EngineName groovy;private static ScriptEngine engine null;static{ScriptEngineManager factory new ScriptEngineManager();engine factory.getEngineByName(EngineName);}public static Object evaluateScript(String script, MapString, Object params) {try {Bindings bindings engine.createBindings();bindings.putAll(params);return engine.eval(script,bindings);} catch (Exception e) {log.error(script脚本执行异常,script:{},params:{},script,params);log.error(script脚本执行异常:,e);return null;}}
}2.groovy shell方式
public class GroovyUtils {private static GroovyShell groovyShell new GroovyShell();private static MapString, Script scriptCache new ConcurrentHashMap();private static T T invoke(String scriptText, String function, Object... objects) throws Exception {Script script;String cacheKey DigestUtils.md5Hex(scriptText);if (scriptCache.containsKey(cacheKey)) {script scriptCache.get(cacheKey);} else {script groovyShell.parse(scriptText);scriptCache.put(cacheKey, script);}return (T) InvokerHelper.invokeMethod(script, function, objects);}
}常用的JVM参数
-XX:HeapDumpOnOutOfMemoryError表示当JVM发生OOM时自动生成DUMP文件。-XX:HeapDumpPath表示生成DUMP文件的路径也可以指定文件名称。-Xms 启动应用时JVM 堆空间的初始大小值。
-Xmx 应用运行中JVM 堆空间的极限值。为了不消耗扩大JVM堆空间分配的开销将此参数和-Xms这个两个值设为相等考虑到需要开线程将此值设置为总内存的80%.
-Xss 单个线程堆栈大小值JDK5.0以后每个线程堆栈大小为1M以前每个线程堆栈大小为256K
-Xms 的默认值是物理内存的 1/64 但小于1G-Xmx 的默认值是物理内存的 1/4 但小于1G
-Xmn 此参数硬性规定堆空间的新生代空间大小推荐设为堆空间大小的1/4。
-XX:UseParNewGC 开启此参数多个CPU可并发进行垃圾回收可提高垃圾回收的速度。此参数和UseParallelGC-XX:ParallelGCThreads搭配使用。
UseParallelGC 年轻代使用并发收集而年老代仍旧使用串行收集 。可提高系统的吞吐量。
XX:ParallelGCThreads 年轻代并行垃圾收集的前提下对并发也有效果的线程数增加并行度.此值最好配置与处理器数目相等
-Xloggc:file 将 GC 状态记录在文件中 (带时间戳)
JVM 参数关系到系统的性能而其中 -XX:PermSize-XX:MaxPermSize-Xms-Xmx 和 -Xmn 这 5 个参数更是直接关系到系统的性能系统是否会出现内存溢出。
-XX:PermSize 和 -XX:MaxPermSize 分别设置应用服务器启动时永久存储区的初始大小和极限大小在生产环境中强烈推荐将这个两个值设置为相同的值以避免分配永久存储区的开销,如果不进行设置-XX:MaxPermSize 则默认值为 64M (jdk1.8之前使用)
-XXMaxMetaspaceSize 设置元空间最大值 默认是-1 即不限制 或者说只受限于本地内存大小。
-XXMetaspaceSize 指定元空间触发Fullgc的初始阈值(元空间无固定初始大小) 以字节为单位默认是21M达到该值就会触发
full gc进行类型卸载 同时收集器会对该值进行调整 如果释放了大量的空间 就适当降低该值 如果释放了很少的空间 那么在不超
过-XXMaxMetaspaceSize如果设置了的话 的情况下 适当提高该值。这个跟早期jdk版本的-XX:PermSize参数意思不一样-
XX:PermSize代表永久代的初始容量。-Xloggc:/path/logs/gc-%t.log GC日志存储的文件路径%t 表示每次启动时用时间戳命名日志文件如 gc-2021-03-29_20-41-47.log。
-XX:UseGCLogFileRotation 开启日志文件分割
-XX:NumberOfGCLogFiles16 最多分割几个文件超过之后从头开始写
-XX:GCLogFileSize100M 每个文件存储的上限大小超过就触发分割
-XX:PrintGCDetails 打印GC详细信息
-XX:PrintGCDateStamps 打印GC日期戳
-XX:PrintTenuringDistribution 打印对象年龄分布日志分析 GC 时的晋升情况和晋升导致的高暂停
-XX:PrintHeapAtGC GC 后打印堆数据用于对比一下 GC 前后的堆内存情况更直观
-XX:PrintReferenceGC 打印 Reference 处理信息
-XX:PrintGCApplicationStoppedTime 打印 STW 暂停时间
java -XX:PrintCommandLineFlags -version 查看JVM使用什么垃圾收集器-XX:HeapDumpOnOutOfMemoryError-XX:HeapDumpPath./ 路径
jps 查看java进程号
jinfo
jstat
jstack
jamp
jconsole.exe
jvisualvm.exe调优工具Arthas
支持 JDK6 采用命令行交互模式可以方便的定位和诊断 线上程序运行问题。Arthas 官方文档十分详细详见https://alibaba.github.io/arthas 1.用java -jar运行即可可以识别机器上所有Java进程 2. 选择识别的java进程号, 输入即可进入arthas 的控制台 3. 输入dashboard,可以查看整个进程的运行情况线程、内存、GC、运行环境信息 4. 输入thread可以查看线程详细情况 5. 输入 jad加类的全名 可以反编译这样可以方便我们查看线上代码是否是正确的版本 6. 使用 ognl 命令可以查看线上系统变量的值甚至可以修改变量的值 7. 还有很多命令可以在官网查看,进行使用即可
参考
https://www.cnblogs.com/hanease/p/16131868.html https://blog.csdn.net/ld851/article/details/111180179 https://blog.csdn.net/weixin_46017166/article/details/127820176 jvm: https://api.dandelioncloud.cn/article/details/1497067909796171778