找家里做的工作上哪个网站青岛网站建设哪个好

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

找家里做的工作上哪个网站,青岛网站建设哪个好,网站的默认首页,网站服务器租一个月内存泄漏的理解和分类 可达性分析算法来判断对象是否是不再使用的对象#xff0c;本质都是判断一上对象是否还被引用#xff0c;对于这种情况下#xff0c;由于代码的实现不同就会出现很多内存泄漏问题(让JVM误以为此对象还在引用#xff0c;无法回收#xff0c;造成内存泄…内存泄漏的理解和分类 可达性分析算法来判断对象是否是不再使用的对象本质都是判断一上对象是否还被引用对于这种情况下由于代码的实现不同就会出现很多内存泄漏问题(让JVM误以为此对象还在引用无法回收造成内存泄漏) 内存泄漏(memory leak) 严格来说只有对象不会再被程序用到了但是GC又不能回收他们的情况叫内存泄漏 对象X引用对象YX的生命周期比Y的生命周期长那么当Y生命周期结束的时候X依然引用着Y这时候垃圾回收期是不会回收对象Y的如果对象X还引用着生命周期比较短的ABC对象A对引用着对象a,b,c这样可能造成大量无用的对象不能被回收进而占据了内存资源造成内存泄漏直到内存溢出 申请了内存用完了不释放如一共有1024M内存分配了512M的内存一直不回收那么可用内存只有512M仿佛泄露了一部分通俗讲内存泄漏就是【占着茅坑不拉shi】 内存溢出(out of memory) 申请内存时没有足够的内存可以使用通俗一点讲一个厕所三个坑有两个站着茅坑不走(内存泄漏)剩下一个坑厕所一示接待压力大这时一下来了两个人坑位(内存)不够了内存泄漏变成内存溢出了内存泄漏和内存溢出的关系内存泄漏增多最终导致内存溢出 泄漏分类 经常发生发生内存泄露的代码会被多次执行每次执行泄露一块内存偶然发生在某些特定情况下才会发生一次性发生内存泄漏的方法只会执行一次隐式泄漏一直占着内存不释放直到执行结束严格的说这个不算内存泄漏因为最终释放掉了但如果执行时间特别长会导致内存耗尽 Java内存泄漏的8种情况 静态集合类 静态集合类如HashMap、LinkedList等如果这些容器为静态的那么它们的生命周期与JVM程序一致则容器中对象在程序结束这前将不能被释放从而造成内存泄漏简单而言长生命周期的对象持有短生命周期对象的引用尽管生命周期的对象不再使用但是因为长生命周期对象持有它的引用而导致不能被回收。 public class MemoryLeak {static List list new ArrayList();public void oomTests() {Object obj new Object(); //局部变量方法执行完成后不能被回收因为被list所持有(list是静态变量生命周期同类)list.add(obj);} }单例模式 单例模式和静态集合导致内存泄漏的原因类似因为单例的静态特性它的生命周期和JVM的生命周期一样长所以如果单例对象如果持有外部对象的引用那么这个外部对象也不会被回收那么就会造成内存泄漏。 内部类持有外部类 内部类持有外部类如果一个外部类的实例对象的方法返回一个内部类的实例对象这个内部类对象被长期引用了即使那个外部类实例对象不再被使用但由于内部类持有外部类的实例对象这个外部类对象将不会被垃圾回收这也会造成内存泄漏 各种连接如数据库连接网络连接和IO连接等 各种连接如数据库连接网络连接和IO连接等在对数据库进行操作的过程中首先要建立与数据库连接当不再使用时需要调用close方法来释放与数据库连接只有连接被关闭后垃圾回收器才会回收对应的对象否则在访问数据库的过程中对ConnectionStatement或ResultSet不显性地关闭将会造成大量的对象无法被回收从而引起内存泄漏 public static void main(String[] args) {try {Connection conn null;Class.forName(com.mysql.jdbc.Driver);conn DriverManager.getConnection(url,username,password);Statement stmt conn.createStatement();ResultSet rs stmt.executeQuery(….)} catch(Exception e) { //异常日志} finally {//①关闭结果集 Statement//②关闭声明的对象 ResultSet//③关闭连接 Connection} }变量不合适作用域 变量不合理的作用域一般而言一个变量的定义的作用范围大于其使用范围很有可能会造成内存泄漏另一方面如果没有及时地把对象设置为null,很有可能导致内存泄漏的定义 public class UsingRandom {private String msg;public void receiveMsg() {msg readFromNet(); //从网络中接收数据保存到msg中saveDB(); //将msg保存到数据库中} }上面伪代码通过readFromNet方法把接收到的消息保存到变量msg中然后调用saveDB方法把msg内存保存到数据库此时msg已经没用了由于msg的生命周期与对象的生命周期相同此时msg不能回收因此造成内存泄漏实际msg变量可以放在receiveMsg方法内部 当方法用完那么msg的生命周期就结束了此时就可以回收了另一种方法使用完msg后将msgnull,此时垃圾回收器也会回收msg内存空间 改变哈希值 当一个对象被存储进HashSet集合中后就不能修改这个对象中的那些参与计算哈希值的字段了否则对象修改后的哈希值与最初存储进HashSet集合中的哈希值就不同了在这种情况下即使用在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象也将返回找不到对象的结果这也会导致无法从HashSet集合中单独删除当前对象造成内存泄漏这也是String设置成不可变类型的原因可以放心把String存入HashSet或把String当成HashMap的key值当我们需要把自定义的类保存到散列表时需要保证对象的hashCode不可变 public class ChangeHashCode1 {public static void main(String[] args) {HashSetPoint hs new HashSet();Point cc new Point();cc.setX(10); //hashCode 41hs.add(cc);cc.setX(20); //hashCode 51System.out.println(hs.remove hs.remove(cc)); // falsehs.add(cc);System.out.println(hs.size hs.size()); //2} } class Point {int x;public int getX() {return x;}public void setX(int x) {this.x x;}Overridepublic int hashCode() {final int prime 31;int result 1;result prime * result x;return result;}Overridepublic boolean equals(Object obj) {if (this obj) {return true;}if (obj null) return false;if (getClass() ! obj.getClass()) return false;Point other (Point) obj;if (x ! other.x) return false;return true;} } //执行结果 hs.remove false hs.size 2缓存泄漏 一旦对象引用放入缓存中很容易遗忘比如之前项目在一次上线的时候应用启动奇慢直至夯死因为代码中会加载一个表中的数据到缓存(内存)中测试环境只有几百条数据但是生产环境有几百万的数据。对于这个问题可以使用WeakHashMap代表缓存此种Map的特点是当除了自身有对key的引用外此key没有其他引用那么此map会自动丢弃此值。 public class MapTest {static Map wMap new WeakHashMap();static Map map new HashMap();public static void main(String[] args) {init();testWeakHashMap();testHashMap();}public static void init() {String ref1 new String(object1);String ref2 new String(object2);String ref3 new String(object3);String ref4 new String(object4);wMap.put(ref1,cacheObject1);wMap.put(ref2,cacheObject2);map.put(ref3,cacheObject3);map.put(ref4,cacheObject4);System.out.println(String引用ref1,ref2,ref3,ref4消失);}public static void testWeakHashMap(){System.out.println(WeakHashMap GC前);for (Object o : wMap.entrySet()) {System.out.println(o);}try {System.gc();TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(WeakHashMap GC后);for (Object o : wMap.entrySet()) {System.out.println(o);}}public static void testHashMap() {System.out.println(HashMap GC前);for (Object o : map.entrySet()) {System.out.println(o);}try {System.gc();TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(HashMap GC后);for (Object o : map.entrySet()) {System.out.println(o);}} } //执行结果 String引用ref1,ref2,ref3,ref4消失 WeakHashMap GC前 object2cacheObject2 object1cacheObject1 WeakHashMap GC后 HashMap GC前 object4cacheObject4 object3cacheObject3 HashMap GC后 object4cacheObject4 object3cacheObject3监听器和回调 如果客户端在你实现API注册回调却没有显示的取消就会产生积聚需要确保回调被当作垃圾回收的最佳方法是只保存它的弱引用保存成WeakHashMap的键