天津权健,JAVA内存走漏的原因及处理,奥比岛

频道:推荐新闻 日期: 浏览:221

1. 概述

java 言语的一个重要的特性便是废物搜集器的自动搜集和收回,而不需要咱们手动去办理和开释内存,这也让 java 内存泄露问题愈加难以发现和处理。

假如你的程序抛出了 Exception in thread "main" java.lang.OutOfMemoryError: Java heap space,那么一般这便是因为内存泄露引起的。

2. 什么是内存泄露

总的来说,开释目标的准则便是他再也不会被运用,给一个目标赋值为 null 或许其他目标,就会让这个目标本来所指向的空间变得无法访问,也就再也无法被运用然后等候 GC 的收回。 内存泄露指的便是尽管这部分目标的内存现已不会再被运用,可是他们却不会被 jvm 收回。

  • 一般,假如长生命周期的目标持有短生命周期的引证,就很可能会呈现内存泄露

3. 效果域过大形成的内存泄露

3.1. 问题描绘

public class Simple 美丝沛{
private Object object圣皇衍天诀;
public void method() {
object = new Object();
// ...
}
}

以上的代码中,咱们在 method 办法中为类成员变量 object 赋值了实例化后的值,可是假如咱们只是在这个办法中运用到了 object,那食肉苔在哪将意味着在整个类的生命周期中,object 所占用的空娄文鹏间尽管都不会被再次运用,但却一向无法得以收回,这就形成了内存泄露,假如 object 是一个加入了许多元素的容器,则问题将露出的愈加显着。

3.2. 改善

上述内存泄露代码的改善比较简略。

public class Simple {
private Object object;
public void method() {
object = new Object();
// 运用到 object 的事务代杨俊文码
object = null;
}
}

处理内存泄露问题的准则便是在目标天津权健,JAVA内存泄露的原因及处理,奥比岛不再被运用的时分当即开释相应的引证,因而在事务代码履行后,object 目标不再运用时,赋值为 null,开释他的引证就能够让 jvm 收回相应的内存了。

下面是一段 jd高兴学苑k8 LinkedList 的源码。

//删去指定节点并回来被删去的元素值
E unlink(Node x) {
//获取当时值和前后节点
final E element = x.item;
final Node next = x.next;
final Node prev = x.prev;
if (prev == null) {
//假如前一个节点为空(如当时节点为首节点),后一个节点成为新的首节点
first = next;
} else {
//假如前一个节点不为空,那么他先后指向当时的下一个节点
prev.next = next;
x.prev = null;
}
if (next == null) {
//假如后一个节点为空(如当时节点为尾节点),当时节点前一个成为新的尾节点
last = prev;
} else {
//假如后一个节点不为空,后一个节点向前指向当时的前一个节点
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}

能够看到,在对 x 天津权健,JAVA内存泄露的原因及处理,奥比岛的成员 next、item、prev 的运用完毕后,都显式赋值了 null,避免他们无法被 jvm 收回,在实践开发中,很简略被疏忽。

4. 容器元素形成的内存歧途

4.1. 问题描绘

下面是咱们经过 ArrayList 完成的一个 pop 办法。

public E pop(){
if金历旭(size == 0)
re天津权健,JAVA内存泄露的原因及处理,奥比岛turn null;
else
return (E) elementData[--size];
}

完成起来十分简略,可是却存在着内存泄露的问题,因为 size 变小导致 ArrayList 华夏有的通百艺视频结尾元素将永久得株洲千金电影城影讯不到运用,可是因为容器持有着他们的引证,他们也永久得不到开释。

4.2. 改善

public E pop(){
if(size == 0)
return null;
else{
E e = (E) elementData[--size];
elementData[size] = null;
return e;
}
}

经过自动赋值为 null 然后开释相应元素的引证,然后让相应的空间得以收回。

5. 容器自身形成的内存泄露

5.1. 问题描绘

Vector vec = new Vector();
for (int i = 1; i < 100; i++)
{
Object obj = new Object();
vec.add(obj);
// 运用 obj 的相关事务逻辑
obj = null;
}
// 运用 vec 的相关事务逻辑

上面的代码是一个十分经典的比如,乍看之下没有任何问题,每次运用元素后,将元素引证置为 null,确保了 object 空间的收回。 可是,事实上,容器自身跟着不断的扩容,也占用着十分大的内存,这是常常被疏忽的,假如不将容器自身赋值天津权健,JAVA内存泄露的原因及处理,奥比岛为 null,则容器自身会在作巨阴族用域内一向存活。

5.2. 改善

Vector vec = new Vector();
for (int i = 1; i < 100; i++)
{
Object obj = new Object();
vec.add(obj);
// 运用 obj 的相关事务逻辑
obj = null;
}
// 运用 vec 的相关事务逻辑
vec = null;

改善办法也很简略,在不再运用容器的时分当即赋值为 null 总是最正确的。

6. Set、Map 容器运用默许 equals 办法形成的内存泄露

6.1. 问题描绘

public class TestClass implements Cloneable {
private Long value;
public Long getId() {
return id;
}
public void s天津权健,JAVA内存泄露的原因及处理,奥比岛etId(Long id) {
this.id = id;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class MainClass {
public Set method(List testList)
throws CloneNotSupportedException {
Set result = new HashSet<>();
for (int a = 0; a相似91 < 100000) {
for (TestClass test : testList) {
result.add(test.clone());
}
}
}
}

看上去,上述代码完成了对传入的 testList 去重的代码逻辑,尽管重复了许多许屡次,但咱们的去重代码并不会形成额定的空间糟蹋。 可是事实上,clone、new 操作都是从头在内存中分配空间,这也就意味着他们的地址丧命情网是不同的,而一切的类因为都承继了 顾宁冷少霆Object,所以他们的 equals 办法都来源于 Object 类,默许的完成是回来目标地址。 因而,尽管是 clone 得到的目标在 Set 中去重,可是 Set 仍是以为他们是不同的目标,然后重复增加形成终究抛出 OutOfMemoryError。

6.2. 改善

改善办法很简略,关于自定义的类,增加所需的恰当 equa眼睁睁造句ls 办法的完成即可。

public class TestClass imple天津权健,JAVA内存泄露的原因及处理,奥比岛ments Cloneable {
private Long value;
public Long getId() {
return id;
}
public void 天津权健,JAVA内存泄露的原因及处理,奥比岛setId(Long id) {
this.id = id;
}
@Override
public Object clone() throws CloneNotSupportedE简子涕泣xceptio布什卖热狗n {
return super.clone();
}
@Over徐冬冬15ride
public boolean equals(Object obj) {
return巨浪钱袋 Objects.equals(obj.value, value);
}
}
public class MainClass {
public Set method(List testList)
throws CloneNotSupportedException {
Set result = new Ha合肥丝足会所shSet<>();
for (int a = 0; a < 100000) {
for (TestClass test : testList) {
result.add(test.clone());
}
}
}
}

note:预防为主,医治为辅

热门
最新
推荐
标签