Jvm内存泄漏

时间:2023-01-07 19:28:49

内存泄漏和内存溢出的关系

内存泄露:指程序中动态分配内存给一些临时对象,但是对象不会被GC所回收,它始终占用内存。即被分配的对象可达但已无用。

内存溢出:指程序运行过程中无法申请到足够的内存而导致的一种错误。内存溢出通常发生于OLD段或Perm段垃圾回收后,仍然无内存空间容纳新的Java对象的情况。

从定义上可以看出内存泄露是内存溢出的一种诱因,但是不是唯一因素。

可以使用Runtime.getRuntime().freeMemory()进行内存泄漏查询

Runtime.getRuntime().freeMemory()表示当前还有多少空闲内存

package com.one.util;

public class Hello {
public static void main(String[] args) {
System.out.println("free内存:" + Runtime.getRuntime().freeMemory() / 1024
/ 1024);
String[] aaa = new String[2000000];
for (int i = 0; i < 2000000; i++) {
aaa[i] = new String("aaa");
}
System.out.println("free内存:" + Runtime.getRuntime().freeMemory() / 1024 / 1024);
}
}

此时结果如下所示

Jvm内存泄漏

内存泄漏的例子

如果长生命周期的对象持有短生命周期的引用,就很可能会出现内存泄露

比如下面的代码,这里的object实例,其实我们期望它只作用于method1()方法中,且其他地方不会再用到它,但是,当method1()方法执行完成后,object对象所分配的内存不会马上被认为是可以被释放的对象,只有在Simple类创建的对象被释放后才会被释放,严格的说,这就是一种内存泄露。

public class Simple {

    Object object;

    public void method1(){
object = new Object();
//...其他代码
}
}

怎么解决上面的问题呢,加上下面的蓝色代码注释就好了

public class Simple {

    Object object;

    public void method1(){
object = new Object();
//...其他代码
// 蓝色代码注释开始
object = null;
// 蓝色代码注释结束
}
}

集合里面的内存泄漏

集合里面的数据都设置成null,但是集合内存还是存在的

比如下面的代码

因为你已经在下面的蓝色代码注释里面进行company=null了,所以下面的list集合里面的数据都是无用的了,但是此时list集合里面的所有元素都不会进行垃圾回收

package com.four;

import java.util.ArrayList;
import java.util.List; public class Hello {
public static void main(String[] args) {
List<Company> list = new ArrayList<Company>();
int i=0;
for(int j=0;j<10;j++){
Company company = new Company();
company.setName("ali");
list.add(company);
// 蓝色代码注释开始
company = null;
// 蓝色代码注释结束
} System.gc();
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("已经测试了"+(++i)+"秒");
}
} } class Company {
private String name; @Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("回收Comapny");
} public void setName(String name) {
this.name = name;
} public String getName() {
return name;
}
}

Jvm内存泄漏

怎么解决上面的问题呢,就是把上面的list集合变量也变成null,比如加上下面的红色代码注释

package com.one.util;

import java.util.ArrayList;
import java.util.List; public class Hello {
public static void main(String[] args) {
List<Company> list = new ArrayList<Company>();
int i = 0;
for (int j = 0; j < 10; j++) {
Company company = new Company();
company.setName("ali");
list.add(company);
// 蓝色代码注释开始
company = null;
// 蓝色代码注释结束
}
// 红色代码注释开始
list = null;
// 红色代码注释结束
System.gc();
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("已经测试了" + (++i) + "秒");
}
} } class Company {
private String name; @Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("回收Comapny");
} public void setName(String name) {
this.name = name;
} public String getName() {
return name;
}
}

此时结果如下所示,可以看出来集合里面的Company变量都回收了

Jvm内存泄漏

还有就是使用remove()方法进行移除元素的时候,也可能会造成内存泄漏

什么意思呢,

就比如ArrayList里面的pop(),如果是下面的写法就会造成内存泄漏,因为下面的elementData[--size]这个元素移除之后,并没有进行设置成null

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

所以上面的代码应该变成下面这样,此时注意下面的蓝色代码注释里面的size值比下面的红色代码注释里面的size小1

public E pop(){
if(size == 0)
return null;
else{
// 红色代码注释开始
E e = (E) elementData[--size];
// 红色代码注释结束
// 蓝色代码注释开始
elementData[size] = null;
// 蓝色代码注释结束
return e;
}
}

连接没有关闭会泄漏

比如数据库连接(dataSourse.getConnection()),网络连接(socket)和io连接,这些链接在使用的时候,除非显式的调用了其close()方法(或类似方法)将其连接关闭,否则是不会自动被GC回收的。其实原因依然是长生命周期对象持有短生命周期对象的引用。所以我们经常在网上看到在连接调用结束的时候要进行调用close()进行关闭,这样可以回收不用的内存对象,增加可用内存。

能看到这里的同学,就帮忙点个推荐吧吧,Thanks♪(・ω・)ノ

原文链接

Jvm内存泄漏的更多相关文章

  1. Java JVM 内存泄漏--全解析和处理办法 &lbrack; 转载 &rsqb;

    Java JVM 内存泄露——全解析和处理办法 [转载]   @author 小筐子 @address http://www.jianshu.com/p/bf159a9c391a         JA ...

  2. 排查JVM内存泄漏的命令

    1. jps 使用 jps -l -m 获取到当前jvm进程的pid,通过上述命令获取到了服务的进程号 jps(JVM Process Status Tool):显示指定系统内所有的HotSpot虚拟 ...

  3. jconsole工具使用----jvm内存泄漏问题

    转载地址:https://www.cnblogs.com/baihuitestsoftware/articles/6405580.html Jconsole,Java Monitoring and M ...

  4. java&period;lang&period;OutOfMemoryError&colon; PermGen space (jvm内存泄漏解决办法)

    2.在myeclipse根目录 打开myeclipse.ini 3.在myeclipse中配置内存

  5. 快速串讲——JVM内存的区域划分

    目的 快速定位JVM内存泄漏或者溢出等问题. 面试基础题,加分项. 文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍. 程序计数器(Progra ...

  6. Java内存泄漏分析系列之六:JVM Heap Dump(堆转储文件)的生成和MAT的使用

    原文地址:http://www.javatang.com JVM Heap Dump(堆转储文件)的生成 正如Thread Dump文件记录了当时JVM中线程运行的情况一样,Heap Dump记录了J ...

  7. 运维-JVM监控之内存泄漏

    转载:https://blog.csdn.net/zdx_csdn/article/details/71214219 jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法.堆配置参数 ...

  8. JVM的内存管理、对象的生命周期、内存泄漏

    1 JVM内存 分为“堆”.“栈”和“方法区”三个区域,分别用于存储不同的数据 1.1 堆 JVM在其内存空间开辟一个称为”堆”的存储空间,这部分空间用于存储使用new关键字所创建的对象. 1.2 栈 ...

  9. 说说JVM原理?内存泄漏与溢出的区别?何时产生内存泄漏?

    1.JVM原理 JVM是Java Virtual Machine(Java虚拟机)的缩写,它是整个java实现跨平台的最核心的部分,所有的Java程序会首先被编译为.class的类文件,这种类文件可以 ...

随机推荐

  1. 利用django创建一个投票网站(五)

    创建你的第一个 Django 项目, 第五部分 这一篇从第四部分(en)结尾的地方继续讲起.我们在前几章成功的构建了一个在线投票应用,在这一部分里我们将其创建一些自动化测试. 自动化测试简介 自动化测 ...

  2. 基于webdriver的jmeter性能测试-通过jmeter实现jar录制脚本的性能测试

    续接--基于webdriver的jmeter性能测试-Eclipse+Selenium+JUnit生成jar包 在进行测试前先将用于支持selenium录制脚本运行所需的类包jar文件放到jmeter ...

  3. div根据内容改变大小并且左右居中

    div{ display:inline-block; width:auto; } 这个div的父元素text-align:center;

  4. 一个Java线程死锁的例子

    package com.lk.B; public class Test4 { private static final Object o1 = new Object(); private static ...

  5. error while loading shared libraries&colon; libevent-2&period;0&period;so&period;5解决办法

    安装memcache时,需要建立文件索引或者说文件连接(link),类似windows下的快捷方式 启动服务时出现 error while loading shared libraries: libe ...

  6. Unity3D 之武器系统冷却功能的实现方式

    先上方法 //如果Fire1按钮被按下(默认为ctrl),每0.5秒实例化一发子弹 public GameObject projectile; public float fireRate = 0.5F ...

  7. angular的&dollar;q服务和promise模式

    此承诺/延迟(promise/deferred)实现的灵感来自于 Kris Kowal's Q CommonJS Promise建议文档 将承诺(promise) 作为和 异步执行操作(action) ...

  8. 网页class命名规范

    CSS样式命名整理 页面结构 容器: container/wrap 总体宽度:wrapper 页头:header 内容:content 页面主体:main 页尾:footer 导航:nav 側栏:si ...

  9. iOS objc&lowbar;msgSend 野指针Crash 从 Log 提取 Crash 时 selector 的地址和名字并打印

    从 crash stack log 里面,提取 objc_msgSend 关键字,定位是否是野指针问题导致的crash,如果是则打印 crash 时的 objc_msgSend 调用的第二个参数,即 ...

  10. Linux下使用RedisPool时报错:redis&period;clients&period;jedis&period;HostAndPort getLocalHostQuietly 严重&colon; cant resolve localhost address

    项目在本地无错误,当部署到linux服务器以后,启动tomcat报错: 意思是找不到服务的名称. 后在网上检索相关答案,是因为在/etc/hosts文件中没有加入当前服务器实例的名称,将当前服务器实例 ...