java既然存在gc线程,为什么还存在内存泄漏?
java既然存在gc线程,为什么还存在内存泄漏?
1.既然 Java 的垃圾回收机制能够自动的回收内存,怎么还会出现内存泄漏的情况呢?这个问题,我们需要知道 GC 在什么时候回收内存对象,什么样的内存对象会被 GC 认为是“不再使用”的。
Java中对内存对象的访问,使用的是引用的方式。在 Java 代码中我们维护一个内存对象的引用变量,通过这个引用变量的值,我们可以访问到对应的内存地址中的内存对象空间。在 Java 程序中,这个引用变量本身既可以存放堆内存中,又可以放在代码栈的内存中(与基本数据类型相同)。 GC 线程会从代码栈中的引用变量开始跟踪,从而判定哪些内存是正在使用的。如果 GC 线程通过这种方式,无法跟踪到某一块堆内存,那么 GC 就认为这块内存将不再使用了(因为代码中已经无法访问这块内存了)。
通过这种有向图的内存管理方式,当一个内存对象失去了所有的引用之后,GC 就可以将其回收。反过来说,如果这个对象还存在引用,那么它将不会被 GC 回收,哪怕是 Java 虚拟机抛出 OutOfMemoryError 。
2.java内存泄漏的根本原因是?
答:内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。
3.堆溢出:静态集合类中存储对象
java.lang.OutOfMemoryError: Java heap space
4.栈溢出
java.lang.StackOverflowError
5.代码栈是什么?
答:
Vector v = new Vector( 10 );
for ( int i = 1 ;i < 100 ; i ++ ){
Object o = new Object();
v.add(o);
o = null ;
}
在这个例子中,代码栈中存在Vector 对象的引用 v 和 Object 对象的引用 o 。
在 For 循环中,我们不断的生成新的对象,然后将其添加到 Vector 对象中,之后将 o 引用置空。问题是当 o 引用被置空后,
如果发生 GC ,
我们创建的 Object 对象是否能够被 GC 回收呢?
答案是否定的。
因为, GC 在跟踪代码栈中的引用时,
会发现 v 引用,而继续往下跟踪,就会发现 v 引用指向的内存空间中又存在指向 Object 对象的引用。也就是说尽管 o 引用已经被置空,
但是 Object 对象仍然存在其他的引用,是可以被访问到的,所以 GC 无法将其释放掉。
如果在此循环之后, Object 对象对程序已经没有任何作用,
那么我们就认为此 Java 程序发生了内存泄漏。 7.内存泄漏在哪个领域比较常见?
答:在移动设备对于内存和 CPU都有较严格的限制的情况下, Java 的内存溢出会导致程序效率低下、占用大量不需要的内存等问题。这将导致整个机器性能变差,
严重的也会引起抛出 OutOfMemoryError ,导致程序崩溃。
8.如何避免内存泄漏?
答:明确引用变量的生命周期,是方法内部的局部变量,还是类实例变量,与类实例生命周期相同的要声明为实例变量。
要避免这种情况下的内存泄露,要求我们以C/C++ 的内存管理思维来管理自己分配的内存。第一,是在声明对象引用之前,明确内存对象的有效作用域。在一个函数内有效的内存对象,应该声明为 local 变量,与类实例生命周期相同的要声明为实例变量……以此类推。第二,在内存对象不再需要时,记得手动将其引用置空。
java既然存在gc线程,为什么还存在内存泄漏?的更多相关文章
- 在 POSIX 线程编程中避免内存泄漏
检测和避免 POSIX 线程内存泄漏的技巧 POSIX 线程(pthread)编程定义了一套标准的 C 编程语言类型.函数和常量 — 且 pthreads 提供了一种强大的线程管理工具.要充分使用 p ...
- Java 理论与实践: 用弱引用堵住内存泄漏---转载
要让垃圾收集(GC)回收程序不再使用的对象,对象的逻辑 生命周期(应用程序使用它的时间)和对该对象拥有的引用的实际 生命周期必须是相同的.在大多数时候,好的软件工程技术保证这是自动实现的,不用我们对对 ...
- Java 理论与实践: 用弱引用堵住内存泄漏
弱引用使得表达对象生命周期关系变得容易了 虽然用 Java™ 语言编写的程序在理论上是不会出现“内存泄漏”的,但是有时对象在不再作为程序的逻辑状态的一部分之后仍然不被垃圾收集.本月,负责保障应用程序健 ...
- 解析Java的JNI编程中的对象引用与内存泄漏问题
JNI,Java Native Interface,是 native code 的编程接口.JNI 使 Java 代码程序可以与 native code 交互——在 Java 程序中调用 native ...
- hashCode竟然不是根据对象内存地址生成的?还对内存泄漏与偏向锁有影响?
起因 起因是群里的一位童鞋突然问了这么问题: 如果重写 equals 不重写 hashcode 会有什么影响? 这个问题从上午10:45 开始陆续讨论,到下午15:39 接近尾声 (忽略这形同虚设的马 ...
- 引用计数gc机制使用不当导致内存泄漏
上一篇文章找同事review了一下,收到的反馈是铺垫太长了,我尽量直入正题,哈哈 最近dbd压测时发现内存泄漏,其实这个问题去年已经暴露了,参见这篇博客[压测周].当时排查不够仔细,在此检讨下.关于d ...
- java程序员--小心你代码中的内存泄漏
当你从c&c++转到一门具有垃圾回收功能的语言时,程序员的工作就会变得更加容易,因为你用完对象,他们会被自动回收,但是,java程序员真的不需要考虑内存泄露吗? 其实不然 1.举个例子-看你能 ...
- <转>Python的内存泄漏及gc模块的使用分析
一般来说在 Python 中,为了解决内存泄漏问题,采用了对象引用计数,并基于引用计数实现自动垃圾回收.由于Python 有了自动垃圾回收功能,就造成了不少初学者误认为自己从此过上了好日子,不必再受内 ...
- Java Hotspot G1 GC的一些关键技术
G1 GC,全称Garbage-First Garbage Collector,通过-XX:+UseG1GC参数来启用,作为体验版随着JDK 6u14版本面世,在JDK 7u4版本发行时被正式推出,相 ...
随机推荐
- Delphi使用两种不同方法获取系统端口信息--(装载)
Delphi使用两种方法获取windows系统的端口,还可测试发送消息,点击获取端口信息后,可依次得到如下信息:DCB结构大小.波特率大小.XON的临界值.XOFF的临界值.字符位数.奇偶检验位.停止 ...
- C# 弹出确定、取消窗口
if (MessageBox.Show("确定要退出吗?", "", MessageBoxButtons.OKCancel, MessageBoxIcon.Qu ...
- c++基础 - constexpr
const expression常量表达式,指值不会改变,并且在编译过程中就能得到计算结果的表达式. 复杂系统难以分辨一个初始值是否是常量表达式,因此提出constexptr以提示编译器,用来验证变量 ...
- 2018-2019-20175205实验二面向对象程序设计《Java开发环境的熟悉》实验报告
2018-2019-20175205实验二面向对象程序设计<Java开发环境的熟悉>实验报告 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)>< ...
- Mysql如何进行分组,并且让每一组的结果按照某个字段排序,并且获取每一组的第一个字段
select * from (select * from table_name order by id desc) h where h.catagory_id in(value1,value2,val ...
- CentOS与Win7远程桌面互通
在CentOS上装上Rdesktop即可连接Windows,如下命令,第一次执行时报错,提示CredSSP required by server. [root@localhost ~]# rdeskt ...
- vue-cli3使用webpack-spritesmith配置雪碧图
一.背景问题 项目中如果有大量的小图标,如果不使用阿里的iconfont.UI给一个加一个,加一个引用一个,每个图标虽然很小,但是也是一次请求,每次请求都是消耗性能资源的. 二.解决思路 使用webp ...
- docker-images(镜像)
一.获取镜像 docker search NAME 搜索引擎查找镜像 docker pull NAME:<TAG> 拉去镜像 NAME:表示镜像名称/镜像仓库的名称 TAG: 表示镜像的 ...
- iOS日历控件
项目需要,前一阵子重构了下iPad工程,添加了一个滚动无缝日历. 当时没有头绪,网上找了一个源码改吧改吧就上线了(参考链接),这个功能很多而且流畅性也特别好,推荐不会写的可以参考下. 这几天,活不太忙 ...
- 设计模式理解(十)结构型——享元(Flyweight)
最后一个结构型,享元.没有太多的项目经验,对这种模式只有一种概念上的理解,就是为了节约内存等资源,把可重用的东西只申请一次,然后处处调用,同时用Hash进行管理. 直接上图: 代码: /******* ...