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

做h的小说网站有哪些免费职业技能培训网站

做h的小说网站有哪些,免费职业技能培训网站,crmeb多商户源码,去哪网站备案吗内存泄漏与内存溢出 JVM在运行时会存在大量的对象,一部分对象是长久使用的,一部分对象只会短暂使用 JVM会通过可达性分析算法和一些条件判断对象是否再使用,当对象不再使用时,通过GC将这些对象进行回收,避免资源被用…

内存泄漏与内存溢出

JVM在运行时会存在大量的对象,一部分对象是长久使用的,一部分对象只会短暂使用

JVM会通过可达性分析算法和一些条件判断对象是否再使用,当对象不再使用时,通过GC将这些对象进行回收,避免资源被用尽

内存泄漏:当不再需要使用的对象,因为不正确使用时,可能导致GC无法回收这些对象

当不正确的使用导致对象生命周期变成也是宽泛意义上的内存泄漏

内存溢出:当大量内存泄漏时,可能没有资源为新对象分配

举例内存泄漏

接下来将从对象生命周期变长、不关闭资源、改变对象哈希值、缓存等多个场景举例内存泄漏

对象生命周期变长引发内存泄漏
静态集合类
public class StaticClass {private static final List<Object> list = new ArrayList<>();/*** 尽管这个局部变量Object生命周期非常短* 但是它被生命周期非常长的静态列表引用* 所以不会被GC回收 发生内存溢出*/public void addObject(){Object o = new Object();list.add(o);}
}

类卸载的条件非常苛刻,这个静态列表生命周期基本与JVM一样长

静态集合引用局部对象,使得局部对象生命周期变长,发生内存泄漏

饿汉式单例模式
public class Singleton {private static final Singleton INSTANCE = new Singleton();private Singleton(){if (INSTANCE!=null){throw new RuntimeException("not create instance");}}public static Singleton getInstance(){return INSTANCE;}
}

饿汉式的单例模式也是被静态变量引用,即时不需要使用这个单例对象,GC也不会回收

非静态内部类

非静态内部类会有一个指针指向外部类

public class InnerClassTest {class InnerClass {}public InnerClass getInnerInstance() {return this.new InnerClass();}public static void main(String[] args) {InnerClass innerInstance = null;{InnerClassTest innerClassTest = new InnerClassTest();innerInstance = innerClassTest.getInnerInstance();System.out.println("===================外部实例对象内存布局==========================");System.out.println(ClassLayout.parseInstance(innerClassTest).toPrintable());System.out.println("===================内部实例对象内存布局===========================");System.out.println(ClassLayout.parseInstance(innerInstance).toPrintable());}//省略很多代码.....}
}

当调用外部类实例方法通过外部实例对象返回一个内部实例对象时(调用代码中的getInnerInstance方法)

外部实例对象不需要使用了,但内部实例对象被长期使用,会导致这个外部实例对象生命周期变长

因为内部实例对象隐藏了一个指针指向(引用)创建它的外部实例对象

image-20210520194055109.png

实例变量作用域不合理

如果只需要一个变量作为局部变量,在方法结束就不使用它了,但是把他设置为实例变量,此时如果该类的实例对象生命周期很长也会导致该变量无法回收发生内存泄漏(因为实例对象引用了它)

变量作用域设置的不合理会导致内存泄漏

隐式内存泄漏

动态数组ArrayList中remove操作会改变size的同时将删除位置置空,从而不再引用元素,避免内存泄漏

image-20210520214827223.png

不置空要删除的元素对数组的添加删除查询等操作毫无影响(看起来是正常的),只是会带来隐式内存泄漏

不关闭资源引发内存泄漏

各种连接: 数据库连接、网络连接、IO连接在使用后忘记关闭,GC无法回收它们,会发生内存泄漏

所以使用连接时要使用 try-with-resource 自动关闭连接

改变对象哈希值引发内存泄漏

一般认为对象逻辑相等,只要对象关键域相等即可

一个对象加入到散列表是通过计算该对象的哈希值,通过哈希算法得到放入到散列表哪个索引中

如果将对象存入散列表后,修改了该对象的关键域,就会改变对象哈希值,导致后续要在散列表中删除该对象,会找错索引从而找不到该对象导致删除失败(极小概率找得到)

public class HashCodeTest {/*** 假设该对象实例变量a,d是关键域* a,d分别相等的对象逻辑相等*/private int a;private double d;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;HashCodeTest that = (HashCodeTest) o;return a == that.a &&Double.compare(that.d, d) == 0;}@Overridepublic int hashCode() {return Objects.hash(a, d);}public HashCodeTest(int a, double d) {this.a = a;this.d = d;}public HashCodeTest() {}@Overridepublic String toString() {return "HashCodeTest{" +"a=" + a +", d=" + d +'}';}public static void main(String[] args) {HashMap<HashCodeTest, Integer> map = new HashMap<>();HashCodeTest h1 = new HashCodeTest(1, 1.5);map.put(h1, 100);map.put(new HashCodeTest(2, 2.5), 200);//修改关键域 导致改变哈希值h1.a=100;System.out.println(map.remove(h1));//nullSet<Map.Entry<HashCodeTest, Integer>> entrySet = map.entrySet();for (Map.Entry<HashCodeTest, Integer> entry : entrySet) {System.out.println(entry);}//HashCodeTest{a=100, d=1.5}=100//HashCodeTest{a=2, d=2.5}=200}
}

所以说对象当作Key存入散列表时,该对象最好是逻辑不可变对象,不能在外界改变它的关键域,从而无法改变哈希值

image-20210520211835353.png

将关键域设置为final,只能在实例代码块中初始化或构造器中

如果关键域是引用类型,可以用final修饰后,对外不提供改变该引用关键域的方法,从而让外界无法修改引用关键域中的值 (如同String类型,所以String常常用来当作散列表的Key)

缓存引发内存泄漏

当缓存充当散列表的Key时,如果不再使用该缓存,就要手动在散列表中删除,否则会发生内存泄漏

如果使用的是WeakHashMap,它内部的Entry是弱引用,当它的Key不再使用时,下次垃圾回收就会回收掉,不会发生内存泄漏

public class CacheTest {private static Map<String, String> weakHashMap = new WeakHashMap<>();private static  Map<String, String> map = new HashMap<>();public static void main(String[] args) {//模拟要缓存的对象String s1 = new String("O1");String s2 = new String("O2");weakHashMap.put(s1,"S1");map.put(s2,"S2");//模拟不再使用缓存s1=null;s2=null;//垃圾回收WeakHashMap中存的弱引用System.gc();try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}//遍历各个散列表System.out.println("============HashMap===========");traverseMaps(map);System.out.println();System.out.println("============WeakHashMap===========");traverseMaps(weakHashMap);}private static void traverseMaps(Map<String, String> map){for (Map.Entry<String, String> entry : map.entrySet()) {System.out.println(entry);}}
}

结果

image-20210520214132945.png

注意: 监听器和回调 也应该像这样成为弱引用

总结

这篇文章介绍内存泄漏与内存溢出的区别,并从生命周期变长、不关闭资源、改变哈希值、缓存等多方面举例内存泄漏的场景

内存泄漏是指当对象不再使用,但是GC无法回收该对象

内存溢出是指当大量对象内存泄漏,没有资源再给新对象分配

静态集合、饿汉单例、不合理的设置变量作用域都会使对象生命周期变长,从而导致内存泄漏

非静态内部对象有隐式指向外部对象的指针、使用集合不删除元素等都会隐式导致内存泄漏

忘记关闭资源导致内存泄漏(try-with-resource自动关闭解决)

使用散列表时,充当Key 对象的哈希值被改变导致内存泄漏(key 使用逻辑不可变对象,关键域不能被修改)

缓存引发内存泄漏(使用弱引用解决)

最后(一键三连求求拉~)

本篇文章将被收入JVM专栏,觉得不错感兴趣的同学可以收藏专栏哟~

本篇文章笔记以及案例被收入 gitee-StudyJava、 github-StudyJava 感兴趣的同学可以stat下持续关注喔~

有什么问题可以在评论区交流,如果觉得菜菜写的不错,可以点赞、关注、收藏支持一下~

关注菜菜,分享更多干货,公众号:菜菜的后端私房菜

本文由博客一文多发平台 OpenWrite 发布!

http://www.ds6.com.cn/news/31586.html

相关文章:

  • 鹰潭房产网站建设全能搜
  • copyright 个人网站站长之家下载
  • 网络营销类型有哪些上海seo服务外包公司
  • wordpress copyright浙江短视频seo优化网站
  • 在线建设网站 源代码百度投诉中心热线
  • 扶风网站开发网络推广方式有哪几种
  • 网站怎么才能被百度收录服装市场调研报告范文
  • wordpress dz 整合seo外包软件
  • 外贸b2b网站大全一b2b平台网络营销方式方法
  • 360浏览器屏蔽某网站怎么做公司网站建设公司
  • 香港网站空间申请网站如何进行优化
  • 政府门户网站建设经验汇报材料百度下载app下载
  • 个人个性网页界面设计网站搜索优化公司
  • 网站开发设计思想网站推广线上推广
  • 分类信息网站怎么做流量app网站
  • 织梦后台怎么加自己做的网站北京seo优化诊断
  • nodejs做网站容易被攻击吗网络营销策划ppt
  • centos 7安装wordpress深圳优化怎么做搜索
  • 怎么用linux做网站服务器四川成都最新消息
  • 网站建设 网站内容 采集百度移动端排名
  • 做问卷的几个网站百度url提交
  • 加盟的网站建设推广普通话手抄报内容大全资料
  • ppt做视频的模板下载网站有哪些内容河源市企业网站seo价格
  • 佛山市网站建设分站多少钱搜索引擎优化seo专员
  • 网站网页设计制作教程b站在哪付费推广
  • 淘宝上网站建设是什么常见的网络营销手段
  • wordpress网站建设教程网推公司干什么的
  • 关于建设网站的报告写软文一篇多少钱合适
  • 太原本地网站中国网站排名网
  • 网站备案 假通信地址中国十大seo公司