当前位置: 首页 > news >正文

广州海珠网站开发设计兰州装修公司排名前十口碑推荐

广州海珠网站开发设计,兰州装修公司排名前十口碑推荐,个人友情链接推广,wordpress自动安装使用分析工具#xff1a;MAT(Memory Analyzer Tool)、JvisualVM占用内存#xff1a;sun.security.ssl.SSLSocketImpl 一、 项目场景#xff1a; 功能#xff1a;一个定时任务(xxl-job)采用线程池的方式多线程请求第三方拉取数据#xff0c;网络框架使用okhttp3。 问题MAT(Memory Analyzer Tool)、JvisualVM占用内存sun.security.ssl.SSLSocketImpl 一、 项目场景 功能一个定时任务(xxl-job)采用线程池的方式多线程请求第三方拉取数据网络框架使用okhttp3。 问题执行job时内存短时间内暴增导致OOM 二、问题描述 定时任务执行时突然内存激增OOM导致项目重启。下面这张图是重启后再次执行定时任务的内存监控 三、原因分析 3.1 查看堆栈信息 使用MAT查看堆栈信息sun.security.ssl.SSLSocketImpl这个东西占了62% 点击Details 可以看到有9k多个对象 使用OQL查询sun.security.ssl.SSLSocketImpl发现其中的host都是请求第三方的地址 select * from sun.security.ssl.SSLSocketImpl 到这里基本可以定位到是由于请求第三方资源没有释放导致内存暴增。接下来查看请求第三方的代码 3.2 查看代码 看到底层工具类OkHttpClientUtil工具类中获取OkHttpClient对象的代码是这样的每次请求都是new一个OkhttpClient对象可能是每次都是new一个OkhttpClient的问题于是在本地复现。 private static OkHttpClient getHttpClient() {return new OkHttpClient.Builder().connectTimeout(obtainConnectTimeOut(), TimeUnit.MILLISECONDS).writeTimeout(obtainWriteTimeOut(), TimeUnit.MILLISECONDS).readTimeout(obtainReadTimeOut(), TimeUnit.MILLISECONDS).build();}四、场景复现 模拟生产采用线程池方式多线程请求请求地址改为百度数据随便塞一点只要正常相应就行。 4.1代码 OkHttpClientUtil 工具类,getHttpClient()是之前的getHttpClientSingleton()是我新写的 Slf4j public class OkHttpClientUtil {private static final MediaType TYPE_JSON MediaType.parse(application/json; charsetutf-8);private volatile static OkHttpClient okHttpClient;public static OkHttpClient getHttpClient() {return new OkHttpClient.Builder().connectTimeout(30000, TimeUnit.MILLISECONDS).writeTimeout(1800000, TimeUnit.MILLISECONDS).readTimeout(1800000, TimeUnit.MILLISECONDS).build();}/*** 单例双重检测** return*/public static OkHttpClient getHttpClientSingleton() {if (null okHttpClient) {synchronized (OkHttpClient.class) {if (null okHttpClient) {okHttpClient new OkHttpClient.Builder().connectTimeout(30000, TimeUnit.MILLISECONDS).writeTimeout(1800000, TimeUnit.MILLISECONDS).readTimeout(1800000, TimeUnit.MILLISECONDS).build();}}}return okHttpClient;}}测试类 Slf4j SpringBootTest public class SpringAmqpTest {Bean(name banksAssetTaskExecutor)public TaskExecutor assetTaskExecutor() {ThreadPoolTaskExecutor executor new ThreadPoolTaskExecutor();// 设置核心线程数executor.setCorePoolSize(20);// 设置最大线程数executor.setMaxPoolSize(100);// 设置队列容量executor.setQueueCapacity(1000);// 设置默认线程名称executor.setThreadNamePrefix(AssetTaskExecutor-api-thread);// 设置线程池拒绝策略:抛弃旧的executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());// 等待所有任务结束后再关闭线程池executor.setWaitForTasksToCompleteOnShutdown(true);executor.initialize();return executor;}Resourceprivate TaskExecutor assetTaskExecutor;Testpublic void test() throws Exception {final CountDownLatch countDownLatch new CountDownLatch(20);for (int i 0; i 20; i) {assetTaskExecutor.execute(() - {//每个线程执行1000个请求for (int j 0; j 10000; j) {try {long l1 System.currentTimeMillis();Response response requestBaidu();long l2 System.currentTimeMillis();log.info(线程id{},请求响应时间{},相应内容{},, Thread.currentThread().getName(), l2 - l1, response);} catch (Exception e) {log.info(执行失败Excetion:, e);}}countDownLatch.countDown();});}countDownLatch.await();System.out.println(执行完成);}private Response requestBaidu() throws IOException {// //获取OkHttpClient对象(getHttpClient()\getHttpClientSingleton())OkHttpClient okHttpClient OkHttpClientUtil.getHttpClient();MapString, String map new HashMap();map.put(江, 哈哈);String json JSONObject.toJSONString(map);RequestBody body RequestBody.create(TYPE_JSON, json);Request request new Request.Builder().url(https://baidu.com/).post(body).build();Response response okHttpClient.newCall(request).execute();return response;}}4.2 测试结果 4.2.1 每次都new HttpClient 使用getHttpClient()方法获取HttpClient对象(每次请求都new一个新的HttpClient对象) 控制打印可以看到不断的发出请求 使用jvisualvm工具(位于jdk bin目录下) 分析堆情况 执行后发现堆在不断增大 点击菜单上的线程看到一堆的等待线程OkHttp connectionPool(连接池) 将堆信息下载下来用MAT分析 点击右上角堆Dump下载堆信息 使用MAT分析 发现最大占用的两个部分别是sun.security.ssl.SSLSocketImpl 和 okhttp3.ConnectionPool(连接池)场景基本复现。 使用OQL查看 host地址是百度地址,基本复现 4.2.2 使用单例模式 使用getHttpClientSingleton()方法获取HttpClient对象(每次请求都new一个新的HttpClient对象) 使用jvisualVM监控 堆稳定不会不断增加 等待线程也不多 4.3 为什么每次请求都创建OkHttpClient会导致内存溢出 分析完知道导致问题的原因是每次请求都去new一个OkHttpClient那为什么会导致内存溢出呢 路径okhttp3.Dispatcher#executorService可以看到这块代码 public synchronized ExecutorService executorService() {if (executorService null) {executorService new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,new SynchronousQueueRunnable(), Util.threadFactory(OkHttp Dispatcher, false));}return executorService;} 从这里可以知道每个okHttpClient对象在请求的时候都会创建一个线程池(连接池)而且线程池的keepAliveTime是1分钟 由于之前的代码是每次请求都new一个OkHttpClient对象,所以每次请求都会new一个新的线程池在一分钟内大量进行请求的会内存会在短时间内暴涨。 解决办法依就是只使用一个OkHttpClient 五、解决方案 解决方法就是只使用一个OkHttpClient实例而不是每次都去创建 以下两种都可以 使用单例模式使用静态代码块只加载一次。
http://www.huolong8.cn/news/100714/

相关文章:

  • 福建省网站建设公司汽车便宜网站建设
  • 网站前端建设需要学会什么意思seo综合查询工具有什么功能
  • 做外贸必须有公司网站么大型网站设计
  • 个人网站设计作品图片网上银行官网
  • 沧州网站群网站架构图图
  • wordpress网站迁移水利建设管理司网站
  • 昆明网站制作的教程推广用哪个平台效果好
  • 直播做ppt的网站趣图在线生成网站源码
  • 网站提示未备案北京网站搭建哪家好
  • 社科联网站建设情况汇报珠海网站设计平台
  • 网站专题策划中国域名注册局官网
  • 泉州网站seo黔南网站建设
  • 网站设计制作体会游戏源码网站免费
  • 济宁市网站建设有些网站开发人员工具无反应
  • 阿里巴巴怎么做网站remix做歌网站
  • 建设壁纸网站的目的山东网站建设设计
  • 整站优化与关键词排名如何自学广告设计
  • 接网站建设_网站设计综合网站开发
  • 网站设计做啥好互联网营销师报名
  • 怎么做足球网站网站页面设计流程
  • 2019建设什么网站好运营html在哪里写代码
  • 綦江建站哪家正规网站建设素材网
  • 网站推广软文公司网站开发虚拟电话
  • 网站建设的行业代码是多少徐州网站建设xzqjw
  • 网站开发视频教程百度云阿亮seo技术
  • 企业免费建站软件网络设计工资有多少
  • 深圳做网站 信科网络电商网站功能列表
  • 义乌营销型网站建设建设单位应该关注的网站
  • 做景观私活的网站wordpress采集插件 免费下载
  • 城乡与住房建设厅网站首页移动端app是什么意思