精华内容
下载资源
问答
  • Java内存释放

    2019-05-21 18:50:42
    参考博文:Java内存释放

    参考博文:Java内存释放

    展开全文
  • java内存释放

    千次阅读 2015-05-31 14:05:08
    (问题一:什么叫垃圾回收机制?) 垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的...) JAVA语言不允许程序员直接控制内存空间的使用。内存空间的分配和回收都是由JRE负责在后台自动进行的,尤其是
    (问题一:什么叫垃圾回收机制?) 垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的对象,按照特定的垃圾收集算法来实现资源自动回收的功能。当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用,以免造成内存泄露。
    (问题二:java的垃圾回收有什么特点?) JAVA语言不允许程序员直接控制内存空间的使用。内存空间的分配和回收都是由JRE负责在后台自动进行的,尤其是无用内存空间的回收操作 (garbagecollection,也称垃圾回收),只能由运行环境提供的一个超级线程进行监测和控制。
    (问题三:垃圾回收器什么时候会运行?) 一般是在CPU空闲或空间不足时自动进行垃圾回收,而程序员无法精确控制垃圾回收的时机和顺序等。
    (问题四:什么样的对象符合垃圾回收条件?) 当没有任何获得线程能访问一个对象时,该对象就符合垃圾回收条件。
    (问题五:垃圾回收器是怎样工作的?) 垃圾回收器如发现一个对象不能被任何活线程访问时,他将认为该对象符合删除条件,就将其加入回收队列,但不是立即销毁对象,何时销毁并释放内存是无法预知的。垃圾回收不能强制执行,然而Java提供了一些方法(如:System.gc()方法),允许你请求JVM执行垃圾回收,而不是要求,虚拟机会尽其所能满足请求,但是不能保证JVM从内存中删除所有不用的对象。(该方法我试过了,的确有些时候是释放不了内存的)
    (问题六:一个java程序能够耗尽内存吗?) 可以。垃圾收集系统尝试在对象不被使用时把他们从内存中删除。然而,如果保持太多活的对象,系统则可能会耗尽内存。垃圾回收器不能保证有足够的内存,只能保证可用内存尽可能的得到高效的管理。
    (问题七:如何显示的使对象符合垃圾回收条件?)
    (1) 空引用 :当对象没有对他可到达引用时,他就符合垃圾回收的条件。也就是说如果没有对他的引用,删除对象的引用就可以达到目的,因此我们可以把引用变量设置为 null,来符合垃圾回收的条件。(实际上我对下列的方法差不多都试过,发现垃圾回收不是迅速执行的,它会有一个缓慢的过程。)-----给对象赋予了空值null,以后再也没有调用过。
    Java代码
    StringBuffer sb = new StringBuffer("hello");
    System.out.println(sb);
    sb=null;
    (2) 重新为引用变量赋值:可以通过设置引用变量引用另一个对象来解除该引用变量与一个对象间的引用关系。
    -----给对象赋予了新植,及重新分配了内存空间。
    Java代码
    StringBuffer sb1 = new StringBuffer("hello");
    StringBuffer sb2 = new StringBuffer("goodbye");
    System.out.println(sb1);
    sb1=sb2;//此时"hello"符合回收条件
    StringBuffer sb1 = new StringBuffer("hello");
    StringBuffer sb2 = new StringBuffer("goodbye");
    System.out.println(sb1);
    sb1=sb2;//此时"hello"符合回收条件

    (3) 方法内创建的对象:所创建的局部变量仅在该方法的作用期间内存在。一旦该方法返回,在这个方法内创建的对象就符合垃圾收集条件。有一种明显的例外情况,就是方法的返回对象。(如果调用的类终止后,其中的私有变量应该也会被释放)
    Java代码
    public static void main(String[] args) {
    Date d = getDate();
    System.out.println("d = " + d);
    }
    private static Date getDate() {
    Date d2 = new Date();
    StringBuffer now = new StringBuffer(d2.toString());
    System.out.println(now);
    return d2;
    }
    public static void main(String[] args) {
    Date d = getDate();
    System.out.println("d = " + d);
    }
    private static Date getDate() {
    Date d2 = new Date();
    StringBuffer now = new StringBuffer(d2.toString());
    System.out.println(now);
    return d2;
    }

    (4) 隔离引用:这种情况中,被回收的对象仍具有引用,这种情况称作隔离岛。若存在这两个实例,他们互相引用,并且这两个对象的所有其他引用都删除,其他任何线程无法访问这两个对象中的任意一个。也可以符合垃圾回收条件。
    Java代码
    public class Island {
    Island i;
    public static void main(String[] args) {
    Island i2 = new Island();
    Island i3 = new Island();
    Island i4 = new Island();
    i2.i=i3;
    i3.i=i4;
    i4.i=i2;
    i2=null;
    i3=null;
    i4=null;
    }
    }

    public class Island {
    Island i;
    public static void main(String[] args) {
    Island i2 = new Island();
    Island i3 = new Island();
    Island i4 = new Island();
    i2.i=i3;
    i3.i=i4;
    i4.i=i2;
    i2=null;
    i3=null;
    i4=null;
    }
    }

    (问题八:垃圾收集前进行清理 ------finalize()方法) java提供了一种机制,使你能够在对象刚要被垃圾回收之前运行一些代码。这段代码位于名为finalize()的方法内,所有类从Object类继承这个方法。由于不能保证垃圾回收器会删除某个对象。因此放在finalize()中的代码无法保证运行。因此建议不要重写finalize();
    展开全文
  • java管理windows系统内存_java释放内存缓存_java获得CPU使用率_系统内存_硬盘_进程源代码
  • JAVA内存释放机制

    万次阅读 2016-06-20 09:38:11
    内存释放(主要是GC)有关的话题。    ★JVM的内存?  在Java虚拟机规范中(具体章节请看“这里 ”),提及了如下几种类型的内存空间:  ◇栈内存(Stack):每个线程私有的。  ◇堆内存(Heap):所有...
    和内存释放(主要是GC)有关的话题。

     

      ★JVM的内存?

      在Java虚拟机规范中(具体章节请看“这里 ”),提及了如下几种类型的内存空间:

      ◇栈内存(Stack):每个线程私有的。

      ◇堆内存(Heap):所有线程公用的。

      ◇方法区(MethodArea):有点像以前常说的“进程代码段”,这里面存放了每个加载类的反射信息、类函数的代码、编译时常量等信息。

      ◇原生方法栈(Native Method Stack):主要用于JNI中的原生代码,平时很少涉及。

    ?

      ★垃圾回收机制简介?

      其实Java虚拟机规范中并未规定垃圾回收的相关细节。垃圾回收具体该怎么搞,完全取决于各个JVM的设计者。所以,不同的JVM之间,GC的行为可能会有一定的差异。下面咱拿SUN官方的JVM来简单介绍一下GC的机制。

      ◇啥时候进行垃圾回收?

      一般情况下,当JVM发现堆内存比较紧张、不太够用时,它就会着手进行垃圾回收工作。但是大伙儿要认清这样一个残酷的事实:JVM进行GC的时间点是无法精确预知的。因为GC启动的时刻会受到各种运行环境因素的影响,随机性太大。

      虽说咱们无法精确预知,但假如你想知道每次垃圾回收执行的情况,还是蛮方便的。可以通过JVM的命令行参数“-XX:+PrintGC”把相关信息打印出来。

      另外,调用System.gc()只是建议JVM进行GC。至于JVM到底会不会做,那就不好说啦。通常不建议自己手动调用System.gc(),还是让JVM自行决定比较好。另外,使用JVM命令行参数“-XX:+DisableExplicitGC”可以让System.gc()不起作用。

      ◇谁来负责垃圾回收?

      一般情况下,JVM会有一个或多个专门的垃圾回收线程,由它们负责清理回收垃圾内存。

      ◇如何发现垃圾对象?

      垃圾回收线程会从“根集(Root Set)”开始进行对象引用的遍历。所谓的“根集”,就是正在运行的线程中,可以访问的引用变量的集合(比如所有线程当前函数的参数和局部变量、当前类的成员变量等等)。垃圾回收线程先找出被根集直接引用的所有对象(不妨叫集合1),然后再找出被集合1直接引用的所有对象(不妨叫集合2),然后再找出被集合2直接引用的所有对象......如此循环往复,直到把能遍历到的对象都遍历完。

      凡是从根集通过上述遍历可以到达的对象,都称为可达对象或有效对象;反之,则是不可达对象或失效对象(也就是垃圾)。

      ◇如何清理/回收垃圾?

      通过上述阶段,就把垃圾对象都找出来。然后垃圾回收线程会进行相应的清理和回收工作,包括:把垃圾内存重新变为可用内存、进行内存的整理以消除内存碎片、等等。这个过程会涉及到若干算法,有爱好的同学可以参见“这里”。限于篇幅,咱就不深入聊了。

      ◇分代

      早期的JVM是不采用分代技术的,所有被GC管理的对象都存放在同一个堆里面。这么做的缺点比较明显:每次进行GC都要遍历所有对象,开销很大。其实大部分的对象生命周期都很短(短命对象),只有少数对象比较长寿;在这些短命对象中,又只有少数对象占用的内存空间大;其它大量的短命对象都属于小对象(很符合二八原理 )。

       有鉴于此,从JDK 1.2之后,JVM开始使用分代的垃圾回收(Generational GarbageCollection)。JVM把GC相关的内存分为年老代(Tenured)和年轻代(Nursery)、持久代(Permanent,对应于JVM规范的方法区)。大部分对象在刚创建时,都位于年轻代。假如某对象经历了几轮GC还活着(大龄对象),就把它移到年老代。另外,假如某个对象在创建时比较大,可能就直接被丢到年老代。经过这种策略,使得年轻代总是保存那些短命的小对象。在空间尺寸上,年轻代相对较小,而年老代相对较大。

      因为有了分代技术,JVM的GC也相应分为两种:主要收集(Major Collection)和次要收集(MinorCollection)。主要收集同时清理年老代和年轻代,因此开销很大,不常进行;次要收集仅仅清理年轻代,开销很小,经常进行。

    ?

      ★GC对性能会有啥影响??

      刚才介绍了GC的大致原理,那GC对性能会造成哪些影响捏?主要有如下几个方面:

      ◇造成当前运行线程的停顿

      早期的GC比较弱智。在它工作期间,所有其它的线程都被暂停(以免影响垃圾回收工作)。等到GC干完活,其它线程再继续运行。所以,早期JDK的GC一旦开始工作,整个程序就会陷入假死状态,失去各种响应。

      经过这些年的技术改进(包括采用分代技术),从JDK1.4开始,GC已经比较精明了。在它干活期间,只是偶然暂停一下其它线程的运行(从长时间假死变为暂时性休克)。

      ◇遍历对象引用的开销

      试想假如JVM中的对象很多,那遍历完所有可达对象肯定是比较费劲的工作,这个开销可不小。

      ◇清理和回收垃圾的开销

      遍历完对象引用之后,对垃圾的清理和回收也有较大的开销。这部分开销可能包括复制内存块、更新对象引用等等。

    ?

      ★几种收集器?

      ◇两个性能指标

      因为今天聊的是性能的话题,必然会提到衡量GC性能的两个重要指标:吞吐量(Throughput)和停顿时间(PauseTime)。吞吐量这个词不是很直观,解释一下:就是JVM不用于GC的时间占总时间的比率。吞吐量是越大越好,停顿时间是越小越好。

      不同的应用程序对这两个指标的关注点不一样(后面具体会说),也就是所谓的“众口难调”。很多JVM厂商为了迎合“众口”,不得不提供多种几种垃圾收集器供使用者选择。不同的收集器,采用的收集策略是不一样的,下面具体介绍。

      ◇串行收集器(Serial Collector)

      使用命令行选项“-XX:+UseSerialGC”指定。

      这种收集器是最传统的收集器。它使用单线程进行垃圾回收,对于单CPU机器比较合适。另外,小型应用或者对上述两个指标没有非凡要求的,可以使用串行收集器。

      ◇并行收集器(Parallel Throughput Collector)

      顾名思义,这种收集器使用多个线程进行垃圾回收以达到高吞吐量。垃圾回收线程的数量通过命令行选项“-XX:ParallelGCThreads=n”指定。可以设置该数值以便充分利用多CPU/多核。

      当使用命令行选项“-XX:+UseParallelGC”时:它会针对年轻代使用多个垃圾回收线程,对年老代依然使用单个线程的串行方式。此选项最早在JDK1.5引入。

      当使用命令行选项“-XX:+UseParallelOldGC”时:它针对年轻代和年老代都使用多个垃圾回收线程的方式。不过此选项从JDK1.6才开始引入。

      ◇并发收集器(Concurrent Low Pause Collector)

      使用命令行选项“-XX:+UseConcMarkSweepGC”指定。

      这种收集器优先保证程序的响应。它会尽量让垃圾回收线程和应用自身的线程同时运行,从而降低停顿时间。此选项从JDK1.4.1开始支持。

      ◇增量收集器(Incremental Collector)

      自从JDK 1.4.2以来,SUN官方就停止维护该收集器了。所以俺就节省点口水,不多说了。

    ?

      ★如何降低GC的影响??

      ◇尽量减少堆内存的使用

      由于GC是针对存储在堆内存的对象进行的。咱们假如在程序中减少引用对象的分配(也就相应降低堆内存分配),那对于提高GC的性能是很有帮助滴。上次“字符串过滤实战”的帖子给出了一个例子,示范了如何通过降低堆内存的分配次数来提升性能。

    ?

      ◇设置合适的堆内存大小

      JVM的堆内存是有讲究的,不能太大也不能太小。假如堆内存太小,JVM老是感觉内存不够用,可能会导致频繁进行垃圾回收,影响了性能;假如堆内存太大,以至于操作系统的大部分物理内存都被JVM自个儿霸占了,那可能会影响其它应用程序甚至操作系统本身的性能。

      另外,年轻代的大小(或者说年轻代与年老代的比值)对于GC的性能也有明显影响。假如年轻代太小,可能导致次要收集很频繁;假如年轻代太大,导致次要收集的停顿很明显。

      JVM提供了若干和堆内存大小相关的命令行选项,具体如下:

    ------------------------------

    -Xms  设置初始堆内存

    -Xmx  设置最大堆内存

    -Xmn  设置年轻代的大小

    -XX:NewRatio=n  设置年轻代与年老代的比例为“n”

    -XX:NewSize=n  设置年轻代大小为“n”

    ------------------------------

      一般情况下,JVM的默认参数值已经够用。所以没事儿别轻易动用上述选项。假如你非调整不可,一定要做深入的性能对比测试,保证调整后的性能确实优于默认参数值。

    ?

      ◇吞吐量和停顿的取舍

      前面提到了不同应用的众口难调。常见的口味有两种:(1)看重吞吐量,对停顿时间无所谓;(2)侧重于停顿时间。

      对于某些在后台的、单纯运算密集型的应用,属于第一种。比如某些科学计算的应用。这时候建议使用并行收集器。

      对于涉及用户UI交互的、实时性要求比较高、程序需要快速响应的,属于第二种。比如某些桌面游戏、某些电信交换系统。这时候建议使用并发收集器。

    ?

      ★相关的参考资料?

      ◇GC调优资料

      SUN官方提供了若干关于JVM垃圾回收调优的说明文档,JDK 1.4.2请看“这里 ”;JDK 1.5请看“这里 ”;JDK1.6请看“这里 ”。

      ◇JVM命令行选项说明

      这是SUN公司内的某个有心人整理的各种命令行参数大全,在“这里 ”。包括有每个参数所适用的JDK版本。

      ◇虚拟机规范

      “这里 ”是SUN官方的JVM规范。

    展开全文
  • java的GC回收是完全自动的,没有提供相关api手动回收,所有的内存分配和回收权限都在jvm,不在开发人员手里**** 没有绝对的强制垃圾回收的方法,不过可以这样去做: 对于不再引用的对象,及时把它的引用赋为null...
     java的GC回收是完全自动的,没有提供相关api手动回收,所有的内存分配和回收权限都在jvm,不在开发人员手里****
     没有绝对的强制垃圾回收的方法,不过可以这样去做:
    
    1. 对于不再引用的对象,及时把它的引用赋为null。 obj = null;
    2. 如果内存确实很紧张,调用System.gc() 方法来建议垃圾回收器开始回收垃圾。通知GC运行,但是Java语言规范并不保证GC一定会执行。
    3. Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有”作用域”的概念,只有对象的引用才有”作用域”。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。
    展开全文
  • java内存分配及释放

    千次阅读 2015-01-27 09:50:40
    内存管理就是对象的分配和释放问题。   在 Java 中,程序员需要通过关键字 new 为每个对象申请内存空间  ( 基本类型除 外 ) ,所有的对象都在堆  (Heap) 中...
  • Java内存释放心得

    千次阅读 2014-08-20 14:29:46
    1 如果一块内存区域能够重复利用,最好不要申请新的。这个内存区域有可能是系统的一个类,自己的一个内部有数组元素,或者能够放大量数据的结构。 2 最好不要在循环里面申请内存,循环越大,越坏事。换句话说,申请...
  • java内存模型

    千次阅读 多人点赞 2018-11-09 13:09:55
    java内存模型 下图就是java内存模型,但是一般讨论的时候不会画这个图,一般画的是java内存模型抽象结构图(在下文)。Thread Stack就是java内存模型抽象结构图中的本地内存,Heap就是java内存模型抽象结构图中的主...
  • Java内存模型

    千次阅读 2017-05-15 09:31:28
    Java的世界也有属于它自己的内存模型,Java内存模型,即Java Memory Model,简称JMM。由于Java被定义成一种跨平台的语言,所以在内存的描述上面也要能是跨平台的,Java虚拟机试图定义一种统一的
  • Java内存管理

    万次阅读 多人点赞 2016-03-08 21:36:06
    不过看了一遍《深入Java虚拟机》再来理解Java内存管理会好很多。接下来一起学习下Java内存管理吧。请注意上图的这个:我们再来复习下进程与线程吧:进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,...
  • Java String内存释放

    千次阅读 2017-06-02 06:46:00
    Java String内存释放 这是一个坑,Java对于String对象,不进行内存的回收; 处理大数据量的时候,少用String。 与JDK有关系;jdk1.6环境下,内存只占用10M,jdk1.8情况下,内存占用300M package com.test; public ...
  • 用jmap查看java内存,发现[B的内存增长很快且释放慢。请问有哪些原因会导致byte增长快释放慢?求指点。
  • Java手动释放内存

    千次阅读 2018-04-10 11:20:32
    托管的资源不需要开发者理会,垃圾回收器会自动回收,而非托管资源则需要开发者手动回收。...手动调用close就是为了释放这些物理资源,而不是释放这个对象所占的内存。需要手动释放的资源分为两部分...
  • Java内存模型-JMM

    万次阅读 2020-09-29 18:08:23
    Java内存模型-JMM 本文是基于CentOS 7.3系统环境,进行Java内存模型的学习和使用 CentOS 7.3 1. Java内存模型 1.1 什么是Java内存模型 Java内存模型(Java Memory Model)本身是一种规范或者一组规则,通过这组...
  • java内存管理 对象的分配与释放 分配: 程序员通过new为每个对象申请内存空间(基本类型除外下面有介绍,注意局部变量和对象的实例变量的区别)所有对象都在堆中分配空间; 释放: 对象的释放是由垃圾回收机制决定和...
  • Java和c++之间有一堵由内存分配和垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人想出来  java的GC回收是完全自动的,没有提供相关api手动回收,所有的内存分配和回收权限都在jvm,不在开发人员手里...
  • java面试题 - 释放垃圾内存

    千次阅读 2020-02-25 10:11:22
    1.使用Runtime类的那个方法,可以释放垃圾内存? A. exec() B. run() C. invoke() D. gc() 正确答案是:D
  • Java内存区域与内存溢出

    千次阅读 2020-02-09 17:27:55
    内容参考《深入理解JVM虚拟机》,本文JVM均指HotSpot虚拟机。 Java与C语言针对“内存管理”...而在Java中,内存由JVM管理,垃圾回收器GC会帮助开发者自动回收不再被引用的对象来释放内存,使得Java不太会像C语言那...
  • JAVA内存回收】Java 内存回收机制

    万次阅读 2018-10-26 17:43:18
    Java的一个重要优点就是通过垃圾收集器GC (Garbage Collection)自动管理内存的回收,程序员不需要通过调用函数来释放内存。因此,很多程序员认为Java 不存在内存泄漏问题,或者认为即使有内存泄漏也不是程序的责任...
  • 【Java并发编程】Java内存模型

    千次阅读 2019-10-24 20:09:03
    文章目录Java内存模型一、JMM解析二、硬件内存架构三、JMM与硬件内存架构的关联四、Java线程与计算机主内存之间的抽象关系五、Java内存模型中同步八种操作 Java内存模型 一、JMM解析 之前写过一篇文章【Java核心技术...
  • JAVA 内存管理总结

    2020-12-22 18:43:16
     Java内存管理是对象的分配和释放问题。(两部分)  分配 :内存的分配是由程序完成的,程序员需要通过关键字new 为每个对象申请内存空间 (基本类型除外),所有的对象都在堆 (Heap)中分配空间。  释放 :...
  • Java内存区域

    千次阅读 多人点赞 2019-10-30 20:42:05
    正是因为 Java 程序员把内存控制权利交给 Java 虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将会是一个非常艰巨的任务。 运行时数据区域 Jav...
  • Java内存模型详解

    千次阅读 2018-05-29 19:00:32
    有些人喜欢把Java内存模型和Java内存区域Java内存区域详解弄混淆,这两个是完全不同的概念。 什么是java内存模型 Java内存模型:Java内存模型(即Java Memory Model,简称JMM)本身是一种抽象的概念,并不真实存在,...
  • java内存溢出

    2012-04-21 12:21:30
    Java内存管理就是对象的分配和释放 问题。在Java中,程序员需要通过关键字new为每个对象申请内存空间 (基本类型除外),所有的对象都在堆 (Heap)中分配空间。另外,对象的释放是由GC决定和执行的。
  • Java内存管理:在前面的一些文章了解到javac编译的大体过程、Class文件结构、以及JVM字节码指令,下面我们详细了解Java内存区域:先说明JVM规范定义的JVM运行时分配的数据区有哪些,然后分别介绍它们的特点,并指出...
  • 目录 1.介绍 1.1内存溢出和内存泄漏 ...作为一个Java开发者,想必大家都听说过:内存溢出和内存泄漏。但真正了解的人,也许寥寥无几。亦或是,认为两者就是同一种概念的人,也是大有人在。之前有...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 328,996
精华内容 131,598
关键字:

怎么释放java内存

java 订阅