- Garbage Collector优势
当我们在使用一个没有Garbage Collector机制的语言编程的时候,我们会碰到一些很难发现的bug,因为这些bug和我们手动释放内存空间相关。典型的有一下两个问题。
- 空指针,当我们使用一段空间的引用释放了这块空间的时候,可能还有别的引用指向这块空间。但是这块空间已经被释放掉了,所以当我们使用另外一个引用去读取这块空间内容的时候,可能读取的是其他的内容了。这个是我们不想看到的。
- 内存泄露。内存泄露就是程序在运行的过程中,没有引用指向这段空间。但是这段空间也没有明确的释放掉。例如在一个列表中,我们本来是想释放整个列表的,但是我们不小心只释放了第一个节点。这样就会导致内存的泄露。
利用Garbage Collector机制,就能避免上述的两个问题。对于第一个问题,只要还有引用只想某段空间,这段空间就不会被释放掉。内存泄露的话,因为都是Java自己回收的,所以也也不会出现这样的问题,Garbage Collector会释放掉全部没有引用的内存空间。
- Java中有这样的几段空间
- Eden Space(heap),大多数的object都是在这里被创建的,除了一些较大的object。
- Survivor Space(heap),那些在Eden Space的Garbage Collector留下来的Object会在这段空间里。
- Tenured Generation(heap), 那些在Survivor Space经过几次Garbage Collector留下来的Ojbect会进入这个空间,也包括上面提到的一些较大的Object,会直接创建在这段空间里。
- Permanent Generation(non-heap),在这段空间里,包含了
- Java classes
- class的方法,包括字节码
- classes的名字
- 常量
- JVM内部创建的类(java/lang/Object , java/lang/Exception)
- 一些编译器的优化信息
- Code Cache(non-heap),包含一些编译需要的代码,以及native code.
参开的文章的资源:
https://blogs.oracle.com/jonthecollector/entry/presenting_the_permanent_generation
http://stackoverflow.com/questions/2129044/java-heap-terminology-young-old-and-permanent-generations
- HotSpot Generations
这个是Java HotSpot virtual machine (JVM) in Sun’s J2SE 5.0 release中jvm对内存回收的一个实现。这种回收机制的是基于以下的几点考虑的:
- 大多数的object不会存留太长的时间
- 一般很少存在老的object指向新的object
所以新的Object会一直在生成和销毁,所以变化很很快。所以新的object存放的内存空间会使用的十分的平凡。但是存在一些非常稳定的object,他们很少会被销毁。所以如果这些很稳定object和很活跃的object在一起的时候,就会因为要内存的整理,消耗很多额外的时间的空间。
所以这里把这些object分成了young和old两代,然后根据每一代不同的特征,使用不同的Garbage Collector算法。
在上面这样图中,我们可以看到Young Generation和Old Generation.
- Young Generation
Young Generation分成了Eden和Survior Spaces两部分。考虑到在Young Generation中,Object会非常的活跃,所以要提高分配和回收的速度,所以选择了stop-theworld
fashion。即会把在一次回收中,在Eden留下来的会被拷贝到To的空间中,From空间中的那些不是很老的object也会被拷贝到To的空间的,那些很老的会被拷贝到Old Generation空间。这样一下,From和Eden就会变空了。所以第二次的拷贝,也就从Eden和From拷贝到一个空的To空间去。这样的好处是比较的方便快捷,但是内存消耗比较大。我们需要额外的内存。
- Old Generation
考虑到Old Generation中存放的都是一下大的对象,比较稳定的对象,所以要合理的利用空间资源,所以在这边使用的算法是mark-sweep-comact。就是首先扎到那些能通过引用找到的object,进行mark,然后在sweep阶段清楚那些没有mark的对象,最后进行内存空间的紧凑。
附件中有一份java官方的内存管理的文档。
里面还有很多内存管理的方面都没有理解,比如其中的已给并行的算法等。
Java的垃圾收集器能够避免空指针和内存泄露问题,它管理的内存分为Eden、Survivor和Tenured Generation等区域。永久代(Permanent Generation)存储类信息,Code Cache存放编译后的代码。年轻代(Young Generation)采用stop-the-world方式快速回收,而老年代(Old Generation)则存放长期存活的对象。
1282

被折叠的 条评论
为什么被折叠?



