JVM的前世今生

àì夳堔傛蜴生んèń 2023-06-02 07:54 93阅读 0赞

前世

jvm的数据区

分别是方法区(Method Area),Java栈(Java stack),本地方法栈(Native Method Stack),堆(Heap),程序计数器(Program Counter Register)

796399-20190912163230780-552314919.png

在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young ) 又被划分为

三个区域:Eden、From Survivor、To Survivor。

新生代。新建的对象都是用新生代分配内存,Eden空间不足的时候,会把存活的对象转移到Survivor中,新生代大小可以由-Xmn来控制,也可以用-XX:SurvivorRatio来控制Eden和Survivor的比例旧生代。用于存放新生代中经过多次垃圾回收仍然存活的对象。

796399-20190912163341968-1402992120.png

gc的触发条件

充分了解了jvm的内存结构之后,下面我们就来说说什么情况下会触发gc。触发full gc的情况主要有这几种:

(1)System.gc()方法的调用。此方法的调用是建议JVM进行Full GC,虽然只是建议而非一定,但很多情况下它会触发 Full GC,从而增加Full GC的频率,也即增加了间歇性停顿的次数。强烈影响系建议能不使用此方法就别使用,让虚拟机自己去管理它的内存,可通过通过-XX:+ DisableExplicitGC来禁止RMI(Java远程方法调用)调用System.gc。

(2)旧生代空间不足。旧生代空间只有在新生代对象转入及创建为大对象、大数组时才会出现不足的现象,当执行Full GC后空间仍然不足,则抛出错误:java.lang.OutOfMemoryError: Java heap space 。为避免以上两种状况引起的FullGC,调优时应尽量做到让对象在Minor GC阶段被回收、让对象在新生代多存活一段时间及不要创建过大的对象及数组。

(3)Permanet Generation空间满了。Permanet Generation中存放的为一些class的信息等,当系统中要加载的类、反射的类和调用的方法较多时,Permanet Generation可能会被占满,在未配置为采用CMS GC的情况下会执行Full GC。如果经过Full GC仍然回收不了,那么JVM会抛出错误信息:java.lang.OutOfMemoryError: PermGen space 。为避免Perm Gen占满造成Full GC现象,可采用的方法为增大Perm Gen空间或转为使用CMS GC。

(4)通过Minor GC后进入老年代的平均大小大于老年代的可用内存。如果发现统计数据说之前Minor GC的平均晋升大小比目前old gen剩余的空间大,则不会触发Minor GC而是转为触发full GC。

(5)由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小

今生

(1)我们在上传文件写入数据库时,如果同一时间写入上万数据,会导致fullgc

日志如下;

  1. ownerThread current state is BLOCKED, current stackTracejava.lang.OutOfMemoryError: GC overhead limit exceeded

问题代码:

  1. List<Map<String, Object>> res;
  2. try {
  3. URL url = new URL(task.getTaskUrl());
  4. HttpURLConnection conn = (HttpURLConnection)url.openConnection();
  5. InputStream inputStream = new BufferedInputStream(conn.getInputStream());
  6. res = ExcelUtil.handleExcel(inputStream);
  7. } catch (IOException e){
  8. log.error(String.format("任务%s,下载解析异常{}", task.getId()), e);
  9. task.setRemark(e.getMessage());
  10. task.setStatus(BatchQueryStatusEnum.VERIFY_FAIL.getCode());
  11. batchQueryTaskDAO.update(task);
  12. return false;
  13. }

使用阿里的easyexcel解决fullgc问题

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>easyexcel</artifactId>
  4. <version>1.1.2-beat1</version>
  5. </dependency>
  6. List<Map<String, String>> res = new ArrayList<>();
  7. try {
  8. URL url = new URL(task.getTaskUrl());
  9. HttpURLConnection conn = (HttpURLConnection)url.openConnection();
  10. InputStream inputStream = new BufferedInputStream(conn.getInputStream());
  11. ExcelListener excelListener = new ExcelListener(MAX_COUNT, res);
  12. ExcelReader excelReader = EasyExcelFactory.getReader(inputStream, excelListener);
  13. excelReader.read();

(2)我们在读数据库写入excel时,如果同一时间写入上万数据,同一时间循环写入大量对象,导致服务宕机

问题代码:

  1. List<BatchQueryDetailDTO> list = batchQueryDetailService.query(id, type == 1);
  2. try {
  3. XSSFWorkbook wb = this.handle(list, apiName, type);
  4. StringBuilder sb = new StringBuilder();
  5. sb.append("批量查询").append(ThreadSafeDateUtil.format(new Date(), "yyyyMMddHHmmss")).append(".xlsx");
  6. String excelName = sb.toString();
  7. ExcelUtil.export(response, wb, excelName);
  8. } catch (Exception e) {
  9. log.error(String.format("taskId=%d导出批量查询失败,{}", id), e);
  10. }
  11. }

分页解决大量创建对象问题

  1. int pageSize = 2000;
  2. List<BatchQueryDetailDTO> list = new ArrayList<>();
  3. Page<BatchQueryDetailDTO> pageResult = batchQueryDetailService.query(id, 1, pageSize,type == 1);
  4. list.addAll(pageResult.getItems());
  5. int totalPage = pageResult.getTotalNumber() / pageSize + 1;
  6. for(int i = 2; i <= totalPage; i++) {
  7. pageResult = batchQueryDetailService.query(id, i, pageSize,type == 1);
  8. if(CollectionUtils.isNotEmpty(pageResult.getItems())){
  9. list.addAll(pageResult.getItems());
  10. }
  11. }

转载于:https://www.cnblogs.com/wanghongye/p/11512933.html

发表评论

表情:
评论列表 (有 0 条评论,93人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JVM前世今生JVM内存模型

    JVM内存模型所指的是JVM运行时区域,该区域分为两大块 线程共享区域 堆内存、方法区,即所有线程都能访问该区域,随着虚拟机和GC创建和销毁 线程独占区域

    相关 JDBC前世今生

    > “请必须要有自信,你就是一道风景,没必要在别人风景里面仰视。”你好,我是梦阳辰,快来和我一起学习吧! 文章目录 01.JDBC是什么? 02.JDBC快

    相关 Dubbo前世今生

    SOA与服务治理 SOA(面向服务的体系结构)概念由来已久,在10多年前便开始进入到我们广大软件开发者的视线中。SOA是一种粗粒度、松耦合服务架构,服务之间通过简单、精确