首页 > 试题广场 >

下面关于垃圾收集的描述哪个是错误的?

[单选题]
下面关于垃圾收集的描述哪个是错误的?
  • 使用垃圾收集的程序不需要明确释放对象
  • 现代垃圾收集能够处理循环引用问题
  • 垃圾收集能提高程序员效率
  • 使用垃圾收集的语言没有内在泄漏问题
推荐
答案:D
也会有内存泄露问题,例如访问资源文件,流不关闭,访问数据库等连接不关闭
编辑于 2015-02-06 14:19:33 回复(6)
java的垃圾收集机制主要针对新生代和老年代的内存进行回收,不同的垃圾收集算法针对不同的区域。所以java的垃圾收集算法使用的是分代回收。一般java的对象首先进入新生代的Eden区域,当进行GC的时候会回收新生代的区域,新生代一般采用复制收集算法,将活着的对象复制到survivor区域中,如果survivor区域装在不下,就查看老年代是否有足够的空间装下新生代中的对象,如果能装下就装下,否则老年代就执行FULL GC回收自己,老年代还是装不下,就会抛出OUtOfMemory的异常
发表于 2015-08-27 10:14:01 回复(9)
Java的内存分配策略:

Java 程序运行时的内存分配策略有三种,分别是静态分配,栈式分配,和堆式分配,对应的,三种存储策略使用的内存空间主要分别是静态存储区(也称方法区)、栈区和堆区。

  • 静态存储区(方法区):主要存放静态数据、全局 static 数据和常量。这块内存在程序编译时就已经分配好,并且在程序整个运行期间都存在。
  • 栈区 :当方法被执行时,方法体内的局部变量(其中包括基础数据类型、对象的引用)都在栈上创建,并在方法执行结束时这些局部变量所持有的内存将会自动被释放。因为栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
  • 堆区 : 又称动态内存分配,通常就是指在程序运行时直接 new 出来的内存,也就是对象的实例(包括该对象其中的所有成员变量)。这部分内存在不使用时将会由 Java 垃圾回收器来负责回收。
    Java中的内存管理
    Java的内存管理就是对象的分配和释放问题。在 Java 中,程序员需要通过关键字 new 为每个对象申请内存空间 (基本类型除外),所有的对象都在堆 (Heap)中分配空间。
  • 关于提高效率
    • 对象的释放是由 GC 决定和执行的。在 Java 中,内存的分配是由程序完成的,而内存的释放是由 GC 完成的,这种收支两条线的方法确实简化了程序员的工作。但同时,它也加重了JVM的工作。
  • 关于消除循环引用
    • Java使用有向图的方式进行内存管理,可以消除引用循环的问题,例如有三个对象,相互引用,只要它们和根进程不可达的,那么GC也是可以回收它们的。这种方式的优点是管理内存的精度很高,但是效率较低。
    • 另外一种常用的内存管理技术是使用计数器。具体如下:gc清理时的引用计数方式:当引用连接至新对象时,引用计数+1;当某个引用离开作用域或被设置为null时,引用计数-1,GC发现这个计数为0时,就回收其占用的内存。这个开销会在引用程序的整个生命周期发生,并且不能处理循环引用的情况。所以这种方式只是用来说明GC的工作方式,而不会被任何一种Java虚拟机应用。例如COM模型采用计数器方式管理构件,它与有向图相比,精度行低(很难处理循环引用的问题),但执行效率很高。
      有向图
什么是内存泄漏

在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。
有向图

为什么会发生内存泄漏

来先看看下面的例子,为什么会发生内存泄漏。下面这个例子中,A对象引用B对象,A对象的生命周期(t1-t4)比B对象的生命周期(t2-t3)长的多。当B对象没有被应用程序使用之后,A对象仍然在引用着B对象。这样,垃圾回收器就没办法将B对象从内存中移除,从而导致内存问题,因为如果A引用更多这样的对象,那将有更多的未被引用对象存在,并消耗内存空间。

B对象也可能会持有许多其他的对象,那这些对象同样也不会被垃圾回收器回收。所有这些没在使用的对象将持续的消耗之前分配的内存空间。
图片说明
在这个例子中,我们循环申请Object对象,并将所申请的对象放入一个 Vector 中,如果我们仅仅释放引用本身,那么 Vector 仍然引用该对象,所以这个对象对 GC 来说是不可回收的。因此,如果对象加入到Vector 后,还必须从 Vector 中删除,最简单的方法就是将 Vector 对象设置为 null。

Vector v = new Vector(10);
for (int i = 1; i < 100; i++) {
    Object o = new Object();
    v.add(o);
    o = null; 
}

有兴趣看引起内存泄漏的原因的可以参考这篇文章http://www.jb51.net/article/92311.htm

发表于 2017-11-17 14:41:47 回复(1)
选D
A、GC机制可以让开发人员必须要明确何时去释放什么样的对象。虽然有System.gc(),提醒JVM进行一个Full GC,但是到底什么时候执行,都不是人为能控制得。
B、GC最常见得问题就是循环引用得问题,对于最常见得引用计数法而言,就没有方法处理这个问题。但是JVM使用得是可达性分析,所以可以处理。
    1. 引用计数法,给每一个对象上都放一个引用计数器,有引用得时候就+1,失去引用去减1,但是这个样子还是没有办法处理循环引用得问题,所谓得循环引用就是一个类中的属性有其他引用类型,假设一个这个类的某个实例中的某个引用类型的属性指向了某个对象,就算你把这个实例置为null,也还是有引用的。
    2. 所谓的可达性分析,就是使用一系列可以作为GC Roots的对象作为起点,从这些节点往下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链的时候,就证明这个对象不可用。也就是不可达,所以被判定为可回收。
        可以作为GC Roots 的对象有:虚拟机栈中引用的对象,方法区的静态属性引用的对象,常量引用的对象和本地方法栈中JNI(Java Native Interface)引用的对象。
再详细的,给一个我博客的链接,可以看看http://bbblemon.top/2018/04/23/%E6%B7%B1%E5%85%A5%E4%BA%86%E8%A7%A3JVM/
C、没毛病吧
D、OOM和内存泄露都还是有得
    1. OOM,内存溢出,是说原来得内存不够用了
    2. 内存泄漏,说得一个对象没用了,但是不能被回收。
发表于 2018-07-17 09:50:54 回复(0)
垃圾收集就能提高程序员效率?我感觉不到啊。
发表于 2017-07-25 16:49:45 回复(8)
D   不可能没有错误
发表于 2016-01-08 10:03:01 回复(0)
这个当数据的资源没有得到及时的关闭的话,也是会发生内存泄漏的,因为后台的垃圾回收线程也只是做到一个检测的作用,并不会时时刻刻的管理内存.
发表于 2018-10-26 08:20:27 回复(0)
也会有内存泄漏问题,例如访问资源文件,流不关闭,访问数据库等连接不关闭
发表于 2018-09-26 15:24:18 回复(1)
语言都可能存在内存泄露问题
发表于 2015-11-21 21:19:37 回复(0)
java也有内存泄漏 只不过范围比c++小   c++中会存在不可达却又无用的对象  在内存中永远收不回来  而这些在java里不会  因为有gc  但一些情况下可达无用的对象  gc也回收不到 
发表于 2015-08-17 20:19:31 回复(0)
内存泄露(Memory Leak)是指一个不再被使用的对象或者变量还在内存中占有存储空间。在C/C++语言中,内存泄露出现在开发人员忘记释放已分配的内存就会造成内存泄露。在java语言中引入垃圾回收机制,有GC负责进行回收不再使用的对象,释放内存。但是还是会存在内存泄露的问题。
内存泄露主要有两种情况:1.在堆中申请的空间没有释放。2.对象已不再被使用(注意:这里的不在被使用是指对程序来说没有用处,如数据库连接使用后没有关。但是还是存在着引用),但是仍然在内存中保留着。GC机制的引入只能解决第一种情况,对于第2种情况无法保证不再使用的对象会被释放。java语言中的内存泄露主要指第2种情况。
内存泄露的原因:1.静态集合类。如HashMap和Vector。这些容器是静态的,生命周期和程序的生命周期一致,那么在容器中对象的生命周期也和其一样,对象在程序结束之前将不能被释放,从而会造成内存泄露。2.各种连接,如数据库连接,网络连接,IO连接,不再使用时如果连接不释放容易造成内存泄露。3.***,释放对象时往往没有相应的删除***,可能会导致内存泄露。
内存溢出(OOM)是指程序在申请内存时没有足够的内存供使用,进而导致程序崩溃这是结果描述。内存泄露(Memory Leak)最终会导致内存溢出。
编辑于 2017-01-08 22:01:45 回复(10)
不是内在吗,D。所以我选了C
发表于 2021-07-12 21:28:27 回复(0)
选D
A、GC机制可以让开发人员必须要明确何时去释放什么样的对象。虽然有System.gc(),提醒JVM进行一个Full GC,但是到底什么时候执行,都不是人为能控制得。
B、GC最常见得问题就是循环引用得问题,对于最常见得引用计数法而言,就没有方法处理这个问题。但是JVM使用得是可达性分析,所以可以处理。
1. 引用计数法,给每一个对象上都放一个引用计数器,有引用得时候就+1,失去引用去减1,但是这个样子还是没有办法处理循环引用得问题,所谓得循环引用就是一个类中的属性有其他引用类型,假设一个这个类的某个实例中的某个引用类型的属性指向了某个对象,就算你把这个实例置为null,也还是有引用的。
2. 所谓的可达性分析,就是使用一系列可以作为GC Roots的对象作为起点,从这些节点往下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链的时候,就证明这个对象不可用。也就是不可达,所以被判定为可回收。
可以作为GC Roots 的对象有:虚拟机栈中引用的对象,方法区的静态属性引用的对象,常量引用的对象和本地方法栈中JNI(Java Native Interface)引用的对象。
再详细的,给一个我博客的链接,可以看看选D
A、GC机制可以让开发人员必须要明确何时去释放什么样的对象。虽然有System.gc(),提醒JVM进行一个Full GC,但是到底什么时候执行,都不是人为能控制得。
B、GC最常见得问题就是循环引用得问题,对于最常见得引用计数法而言,就没有方法处理这个问题。但是JVM使用得是可达性分析,所以可以处理。
1. 引用计数法,给每一个对象上都放一个引用计数器,有引用得时候就+1,失去引用去减1,但是这个样子还是没有办法处理循环引用得问题,所谓得循环引用就是一个类中的属性有其他引用类型,假设一个这个类的某个实例中的某个引用类型的属性指向了某个对象,就算你把这个实例置为null,也还是有引用的。
2. 所谓的可达性分析,就是使用一系列可以作为GC Roots的对象作为起点,从这些节点往下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链的时候,就证明这个对象不可用。也就是不可达,所以被判定为可回收。
可以作为GC Roots 的对象有:虚拟机栈中引用的对象,方法区的静态属性引用的对象,常量引用的对象和本地方法栈中JNI(Java Native Interface)引用的对象。
再详细的,给一个我博客的链接,可以看看http://bbblemon.top/2018/04/23/%E6%B7%B1%E5%85%A5%E4%BA%86%E8%A7%A3JVM/
C、没毛病吧
D、OOM和内存泄露都还是有得
1. OOM,内存溢出,是说原来得内存不够用了
2. 内存泄漏,说得一个对象没用了,但是不能被回收。http://bbblemon.top/2018/04/23/%E6%B7%B1%E5%85%A5%E4%BA%86%E8%A7%A3JVM/
C、没毛病吧
D、OOM和内存泄露都还是有得
1. OOM,内存溢出,是说原来得内存不够用了
2. 内存泄漏,说得一个对象没用了,但是不能被回收。
发表于 2021-04-09 15:42:44 回复(0)
提高程序效率和提高程序员效率的是有本质区别的,可惜我看漏了一个字。直接就没看D就选了
发表于 2020-11-30 12:48:23 回复(0)
what⁉️ 答案不是应该是D吗?
发表于 2020-07-12 14:45:10 回复(0)
java既然存在gc线程,为什么还存在内存泄漏? https://www.cnblogs.com/panxuejun/p/5888817.html
发表于 2020-05-04 14:43:25 回复(0)
提高程序效率吧
发表于 2020-02-01 00:57:57 回复(0)
也会有内存泄漏问题

发表于 2019-07-25 21:41:29 回复(1)
有内存泄露问题
发表于 2019-05-02 08:17:55 回复(0)
有时候也会存在泄露问题的
发表于 2019-04-29 22:36:38 回复(0)
什么是循环引用呀
发表于 2019-04-02 13:52:46 回复(0)