Java内存管理

来源:互联网 发布:区块链闪电网络 知乎 编辑:程序博客网 时间:2024/04/27 19:48

JVM回收对象的标准是什么?

答:对象是否被引用。也就是说如果对象处于不可到达状态就会被回收掉。

(可恢复状态)失去引用的对象怎么变活?

答:系统的垃圾回收机制准备回收该对形象的时候之前,系统会调用可恢复状态对象的finalize方法进行资源清理,如果在此让一个以上引用变量引用此对象,那么这个对象又为可达对象。

对象引用的分类和区别?

分类 区别 强引用 JVM不会回收强引用所引用的Java对象,可能会导致内存泄露 软引用 系统内存空间足够不会回收,不够才回收 弱引用 每次垃圾回收机制执行都会回收 虚引用 -

什么是Java内存泄露

答:程序运行过程中不断地分配内存空间,那些不再使用得内存空间应该立即回收,如果存有没用的内存没有被回收,就是内存泄露。在操作引用数组或者List时,删除一个元素后要记得把null赋给这个元素。

内存溢出与泄露的区别

  • 内存溢出是指out of memory,是指程序申请内存的时候,没有足够的内存空间使用。
  • 内存泄露是 menory leak,是指程序在申请内存后,无法释放已申请的内存空间,多次泄露堆积的后果很严重,内存泄露最终会导致内存溢出。

垃圾回收算法有哪些?

  • 复制:把堆内分成两个相同的空间,从根开始访问每一个关联的可达到对象,把空间A的可到达对象全部复制到B空间然后回收A空间。
    缺点:需要巨大的复制成本和较多内存
  • 标记清除:从根开始访问所有可到达的对象并进行标记,然后一次性遍历整个内存区域,把没有标记的对象进行回收处理。
    缺点:两次遍历需要较大遍历成本和造成堆内存碎片较多。
  • 标记压缩:从根开始访问所有可达到对象,把他们标记可达到状态后把这些对象搬到一起,这个过程为内存压缩,然后垃圾回收机制再次回收那些不可到达对象所占用的空间。
  • 分代回收:根据一个对象生存时间的长短,再根据不同代采取不同的垃圾回收策略。
    首先把堆分成3个代:Young,Old,Permanent
    Young采用复制算法——频率比较高,Old采用标记压缩——频率比较低,Permannet不用回收,存放一些装载Class、方法的信息
    新生代又分为Eden和Survivor区,新创建的对象都在 Eden区、如果Eden区空间不足,就会讲存活的对象复制到Survivor区,如果Survivor区空间不足,就会将Survivor中一直存活的 对象复制到Old年老区(前提是Old有空间)。当young代内存满,就执行young gc,young gc需要高速、频繁地执行。当old或permanent代内存满,就会执行full gc(magor gc),所有代内存都会gc,一般先young gc后old gc、permanent gc,old 代内存有空间大、因此增长缓慢、gc不频繁,一次full gc花费的时间也较多。

Java内存管理小技巧

1)使用Byte、Short、Integer、Long、Float、Double、Boolean、Character等包装类的实例时,不要采用new而是采用直接量来创建。
2)使用StringBuffer和StringBuilder来进行字符串的连接。
3)尽早释放无用的对象引用
4)尽量少用静态标量
5)避免在经常调用的方法、循环中创建Java对象
6)缓存经常使用到的对象(HashMap)
7)尽量不要使用finalize方法
8)考虑使用软引用

回收手段

1)System.gc();
2)System.runFinalization();

垃圾回收器的设计算法大概有以下几种:

串行回收(Serial)和并行回收(Parallel)

串行回收就是不论有多少个CPU,始终只用一个CPU来执行垃圾回收操作,而并行回收就是把整个回收工作拆分成多个部分,每个部分由一个CPU来负责,从而让多个CPU并行回收,并行回收的执行效率很高,但是复杂度增加,另外会使内存碎片会增加。

并发执行和应用程序停止:

应用程序停止的垃圾回收方式会在执行垃圾回收的同时导致应用程序的暂停,并发执行的垃圾回收虽然不会导致应用程序的暂停,但是由于 并发执行垃圾回收需要解决和应用程序的执行冲突(应用程序可能会在垃圾回收过程中修改对象),因此,可能执行开销比应用程序停止更高,而且执行时也需要更多的内存。

压缩和不压缩和复制:

为了减少内存碎片,支持压缩的垃圾回收器会把所有的获得对象搬迁到一起,然后将之前的占用内存全部回收。
优点;解决了内存碎片问题。缺点:速度较慢。

不压缩的垃圾回收方式:

回收速度快,但分配内存慢,且无法解决内存碎片问题。

复制式的垃圾回收:

回收过程不会长生内存碎片,但是需要复制数据和额外的内存。

标记-清除:

先遍历一次,可达的标为可达,然后再遍历一次,把没标记为可达的进行回收。

标记-压缩:

从根开始访问,标可达,再遍历,把可达的复制到一起,回收不可达的内存。

0 0
原创粉丝点击