java如何快速释放对象内存 java垃圾回收算法决定jvm内存分布吗?为什么?

[更新]
·
·
分类:互联网
3627 阅读

java如何快速释放对象内存

java垃圾回收算法决定jvm内存分布吗?为什么?

java垃圾回收算法决定jvm内存分布吗?为什么?

首先得知道垃圾回收算法有哪些?
垃圾判定方法再说垃圾回收算法有什么之前,我们看看是怎么判断哪些对象是可以回收的,一般有两种方法:
1、引用计数,该方法有循环引用问题
引用计数就是使用一次,引用次数加1,释放减1,当为0的时候就回收了。循环引用问题,就是A引用B,B引用A,这样就永远不会释放了。
2、可达性分析(JVM采用该方法)
可达性分析是从GC Roots对象进行搜索,不能搜索到的就可以回收
GC Roots对象:栈(虚拟机栈和本地栈)中引用的对象;方法区(静态属性)中引用的对象
垃圾回收算法明白了怎么来定义垃圾了,就需要明白有哪些垃圾回收算法:
1、标记--清除(Mark-Sweep)
该算法分为两部分,先把内存中对象中的可回收的对象标记出来,然后清理掉。但是该算法存在一个问题,就是内存碎片。如图中画红色叉的地方是可以回收的,没有划红叉的地方是使用的内存,如果回收之后,都是小内存区域,想分配一段连续的内存就没地方了
2、复制算法
复制算法就是解决了标记清除算法了内存碎片问题。将内存划分为大小相等的两块,每次用一块,一块用完了,就把存活的对象复制到另一块上面,然后把不使用的对象清除。但是代价较高,只能使用一半内存
3、标记整理算法
标记整理也是解决了内存碎片问题,标记清除之间清除了对象,而标记整理是把所有存活对象都移动到一起,再清除不再使用对象。这样解决了内存碎片问题,而且解决了只使用一半内存的问题,但是对象移动效率比较低。
4、分代收集算法
分代收集就是整合了前3种算法。把内存分为新生代和老年代,这样针对不同的年代使用不同的算法。新生代中,大量对象需要清除,可以选择复制算法,只需要复制少量对象;老年代存活对象比较多,可以使用标记清理算法或标记整理算法。
Java堆内存JVM选择的就是分代收集算法,从而决定了JVM内存的分成不同的代来使用不同的算法。
新生代分为适合复制算法,因为对象存活率不高。复制算法意味着要浪费一定的内存,Java的新生代分为Eden和Survivor区,Survivor区又分为from和to区。
对象分配的时候都会进入Eden区,当Eden去空间不足的时候就会发起一次Minor GC,把存活对象移动到Survivor的from区(from区空间不够,进去Old区,to区的对象也会移动到from区),Eden的其他对象可以被清除,这时候from和to区的职责互换,下次就是Eden的存活对象移动到to区,from区的对象也会移动到to区。这样永远只有from和to区其中一块内存空闲。
老年代(Old区),对象进行16次Minor GC才会从新生代进入老年代,老年代只有在Major GC才会进行清理,因为存活对象比较多,可以使用标记清理算法或标记整理算法。Major GC会发生“Stop-The-World”,STW时间越长,对系统影响也就越大。
一个对象除了进行16次(次数可以动态设置)Minor GC才会从新生代进入老年代,大对象也会直接进行老年代
总结希望对你有所帮助。正因为垃圾回收算法,JVM内存才会进行分代提高垃圾回收的效率。

String存放在堆中还是栈中?

堆和栈是Java程序在运行过程中的数据存储区,栈是stack,堆是heap。
堆主要用来存储使用new关键字创建的Java对象和数据,堆中存储的对象和数据都有相应的内存地址值。当堆中存储的对象和数据不再被使用时,Java的JVM会启动垃圾回收机制,自动清除堆中存储的对象和数据。
栈是用来存储临时数据的,如Java对象的引用,函数内部的数据和临时对象,函数执行完毕后,存储在栈中的临时数据会立即被释放。