环境:java1.8   -Xms10m -Xmx10m -XX:+PrintGCDetails

最近在研究GC时,发生一些问题想了好久才想明白,先上测试代码。

import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;class OOMData {private static ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();private static ArrayList<String> list = new ArrayList<>();public void testString() {String a = "www.baidu.com";while (true) {a += (new Random().nextInt(888888888) + new Random().nextInt(999999999)+ getRandomString(123) + getRandomString(345)+ getRandomString(789) + "哈哈哈哈哈啊哈哈哈哈"+ getRandomString(234) );}}public void testStaticMap() {int i = 1;String a = "test";while (true) {map.put(i++, getRandomString(1000));}}public void testStaticList() {while (true) {list.add("test");}}//length用户要求产生字符串的长度public static String getRandomString(int length){String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";Random random=new Random();StringBuffer sb=new StringBuffer();for(int i=0;i<length;i++){int number=random.nextInt(62);sb.append(str.charAt(number));}return sb.toString();}}public class OOMTest {public static void main(String[] args) {OOMData data = new OOMData();data.testStaticList();}}

下面上测试结果:

运行testString()方法抛出的异常为:(即测试字符串方法,jdk1.8以后将字符串常量池转移到堆中,每次字符串改变后都会在堆中新建一个字符串对象,直至内存溢出,这个GC日志分析请移步https://blog.csdn.net/weixin_38342534/article/details/102182145)

java.lang.OutOfMemoryError: Java heap space


运行testStaticMap()方法后抛出的异常为:

java.lang.OutOfMemoryError: GC overhead limit exceeded

运行testStaticList()方法抛出的异常为:

java.lang.OutOfMemoryError: Java heap space

下面这两个我刚开始不是很理解,因为我都使用了static进行修饰,被static修饰的类会存放在元空间,不会占用堆内存,而元空间的大小理论上跟笔记本的物理内存一样大。且报错并不是java.lang.OutOfMemoryError: Metaspace 一个是java.lang.OutOfMemoryError: GC overhead limit exceeded 即程序用98%的时间回收了不到2%的堆内存。一个是java.lang.OutOfMemoryError: Java heap space即堆old区满了。贴出GC日志

testStaticList

testStaticMap

通过GC日志可以看出两个都是因为堆内存被占满导致的OOM,说下原因是因为ArrayList底层是使用的数组,而这个数组是ArrayList定义的成员变量Object[],成员变量是存在堆内存中的,所以才会java heap space。而ConcurrentHashMap底层的链表和红黑树结构也都是在类中定义的成员变量,而每次扩展也都会生成一些新的变量,(底层原理具体请看源码或者别的博客)所以最后young区和old区全部被占满。

这说明,被static修饰的容器容易导致oom不是因为存入了元空间,元空间内存不够导致的,而是因为被static修饰的容器,是GC Roots的对象之一,在它下面进行可达性分析的时候,会一直可达,所以会导致GC的时候,不能被回收,从而导致OOM

被static修饰的map、list GC问题相关推荐

  1. 众所周知,static修饰的成员只实例化一次,而string类型每次赋值都会重新创建一个实例,那么用static修饰string呢?...

    string 类型每次实例化都会重新创建一个实例: 解释:string 类型重载了运算符 "=" ,每次 "=" 操作都是一次 "new". ...

  2. C语言--static修饰变量

    Static在C语言里面有两个作用,第一个是修饰变量,第二个是修饰函数. 1.Static修饰变量 按照作用范围的不同,变量分为局部变量和全局变量.如果用static修饰变量,不论这个变量是全局的还是 ...

  3. simpledateformat 毫秒_阿里巴巴 | 为啥代码中禁用static修饰SimpleDateFormat?

    来自:8rr.co/4KkS 在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗? 通过阅读本篇文章你将了解到: 为什么 ...

  4. 10.1——为什么方法不能用static修饰

    statci表示静态 多用修饰变量.内部类 如果修饰方法表示运行前就存在这个方法,但是类都没有被加载进去  自相矛盾 ----------------------------------------- ...

  5. java static修饰方法_浅析Java中static修饰符

    1.概述 static关键字的中文意思是静态的,该修饰符可以修饰字段.方法.内部类.使用该关键字修饰的内容,在面向对象中static修饰的内容是隶属于类,而不是直接隶属于对象的,所以static修饰的 ...

  6. java中修饰常量的事_浅谈java中的声明常量为什么要用static修饰

    今天定义一个类常量,想着也只有这个类可以用到,就没用static关键字修饰.结果sonar代码检查提示: Rename this field "PERSON_TYPE_USER" ...

  7. C++:Static修饰变量 vs Static修饰函数

    在C++语言中,Static关键字有两个作用:修饰变量和修饰函数. Static修饰全局变量叫做静态全局变量, Static修饰局部变量叫做静态局部变量, Static修饰函数叫做静态函数: 静态全局 ...

  8. 阿里规定代码中禁用static修饰SimpleDateFormat,为何?

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群",加入新技术 来自:8rr.co/4KkS 在项目开发过程中经常遇到时间处理,但 ...

  9. 为什么不能同时用const和static修饰成员函数?

    const修饰的函数: 表示在该函数体内不能修改成员的值,会在函数中添加一个隐式的参数const this*. static修饰的函数没有this指针,与const的用法冲突. 但可以使用static ...

  10. java static 修饰变量吗_Java面试 - static 修饰的变量和方法有哪些特点?

    1.static修饰的变量和方法,在类加载时即被初始化,可直接通过类名.变量名和类型.方法名进行调用. 2.static修饰的变量,在类加载时会被分配到数据区的方法区.类的实例可共享方法区中的变量.如 ...

最新文章

  1. vijos - P1279Leave-绿光(数学归纳法 + python)
  2. pom.xml中spring-boot-starter-test包的使用
  3. matlab regress()
  4. 针对java程序员的好书目录 各帖总结与收集,自用送礼两相宜
  5. 文巾解题 177. 第N高的薪水
  6. VHD安装的Win7 X64系统迁移到VMware虚拟机(P2V)...
  7. 理解Java的封装与接口
  8. qmap不能作为信号与槽的传递_撩妹 | 女生对你有好感的三个信号,千万别错过了...
  9. Cocos2d JS 之消灭星星(十) 关卡配置
  10. VBA实战技巧精粹014:关于Range总结
  11. CAD 卸载工具,完美彻底卸载清除干净cad各种残留注册表和文件
  12. html页面加载蒙版,HTML / CSS - 在图像上创建alpha蒙版
  13. 虚拟机下 centos7 网络间歇性断网
  14. 广义表((a,b),c,d)表头和表尾分别是什么?
  15. 参会记录|全国多媒体取证暨第二届多媒体智能安全学术研讨会(MAS‘2023)
  16. DS二叉树——Huffman编码与解码(不含代码框架)
  17. element 实现 表格 跨页选择
  18. 石油基琥珀酸的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  19. 文件操作细致详解(下)
  20. php+flash头像上传组件

热门文章

  1. springboot写发送邮件报错Field javaMailSender in com.gzh.service.impl.IMailServiceImpl
  2. SPSS数据分析常见问题(差异性研究)
  3. 分享CrystalDiskInfo8.2.4与CrystalDiskMark6.0.2个性版本下载
  4. 四种常见演讲结构对比
  5. excel转置怎么操作_Excel八问八答,新手入门必修课
  6. Matplotlib制作动画
  7. 看工业4.0道路上,美国和德国的不同路径
  8. java 支持 超大上G , 多附件上传
  9. python 开发微信小游戏_Python实现微信找茬小游戏自动进行
  10. 华为是不是培养人工智能人才花费最大的公司?