Java内存管理资料

//

Java把内存划分成两种:一种是栈内存,一种是堆内存。

在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。

当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。

堆内存用来存放由new创建的对象和数组。

在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。

在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。

引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。

>>那么请问栈内存和堆内存应该对应的是硬件中的同一个RAM吧?
是硬件中的同一个RAM,启动一个jvm时向操作系统所申请的那一块内存中,
把其中一部分用于栈,其中一部分用于堆。

>>static变量存储在什么位置呢?
目前的jvm中有两种堆(不排除以后合并为一种堆),
其中一种堆是用于存放由new创建的对象和数组,
另一种堆是用于存放装载进来的类信息,static变量即存储在这个类信息中。


栈内存速度快,堆内存速度慢

//

java 启动设置内存参数:
java -Xms1024m -Xmx2048m  ??
还是java -Xms=32m -Xmx=256m ??

//

每个线程都有自己的内存栈(stack),用来存放局部变量和返回值。所有的线程共享一个内存堆(heap),所有运行时的内存分配都在堆上进行,也就是所有对象都在堆上创建。
内存分配方式有三种:
1 从静态存储区域分配.例如static变量。
2 在栈上创建。各种原始数据类型的局部变量。
3 在堆上创建。对象都是在堆上创建的。程序在运行时候用new来创建对象。

***********************************************************************
分代复制垃圾收集器
 所有新创建的对象都在一个类似栈的内存区域分配(叫做eden)。当这块内存分配完,其中大部分对象已经死亡了。垃圾收集器只要把少数未死亡的长期对象复制到另一块内存,然后直接更新eden的指针就可以了,这些未死亡的对象称未tenured对象。eden中的对象称为young generation,生命较长的对象生存的区域称未old generation.当old generation的内存区域全部分配完,垃圾收集器会进行一次主要垃圾收集(major collection)。主要垃圾收集通常比次要垃圾收集慢,因为所有存活的对象都会被遍历到。

标记垃圾收集器
 在年老代中,通常使用标记垃圾收集器,这种垃圾收集器会从一组根引用开始,遍历所有的对象,如果一个对象被根引用,那么就标记未存活,而存活对象引用的对象也标记为存活,如此循环,其他的对象则被标记为死亡。死亡的对象的内存被回收。
 分两类:
 标记紧缩垃圾收集器 将所有存活的对象复制到一个连续的内存区域,减少内存碎片。
 标记清除垃圾收集器 保留所有存活的对象,而将所有死亡对象的内存空间记录到一个自由空间列表中。

增量垃圾收集器
 增量垃圾收集器的基本原理是时间较长的年老代的垃圾收集分成许多较短的时间间隔来完成。每次只回收一部分内存。对于用户来说好像没有停顿一样(垃圾收集器在运行地时候,会停止JVM中地其他程序的线程程序)。但是增量垃圾收集器不精确地保证停顿地时间。

建议:尽量创建更少的对象,如使用StringBuffer代替String.
建议:JAVA中的null可以告诉垃圾收集器回收内存。
 从JDK1.2开始,为了能更加精确地控制垃圾收集器,java引入了Reference类型。有strong,soft,weak和phantom类型的引用。weak,在内存不足时可以自动地被回收。
******************************************************************************
强可达状态
一个新创建的对象即处于强可达状态。在程序运行一段时间后,如果创建该对象的线程无需通过任何引用类型的对象就可以访问该对象,则该对象也处于强可达状态。


软可达状态
 当对象不处于强可达的状态,并且可以通过软引用进行访问时,即处于软可达状态。在程序申请内存时,垃圾收集器会自行判断是否回收处于软可达状态的对象。如果决定回收该对象,那么垃圾收集器会清除所有指向该对象的软引用。如果任何其他处于软可达状态的对象可以通过强引用访问该对象,那么指向这些对象的软引用也会被清除。
 垃圾收集器在决定那些软可达状态的对象被回收时,采用的是“最久未使用”原则。
 创建一个软引用代码:
 SoftReference wRef = new SoftReference(ref);
 也可以将软引用登记在一个引用队列中:
 Reference aQueue = new ReferenceQueue();
 SoftReference sRef = new SoftReference(new SomeObject(),aQueue);


弱可达状态
 当对象既不处于强可达,也不处于软可达的状态,但可以通过弱引用进行访问,即处于弱可达状态。弱可达状态比软可达状态更弱一些。垃圾收集器会一起清除所有的弱引用,而不是像对软引用那样提供一个缓冲的空间。



幻可达状态
 如果一个对象不是强可达,软可达和弱可达中的任何一种状态,其finalize()方法已经被执行过,并且被幻引用指向,那么该对象处于幻可达状态。
 与软引用和弱引用不同,不能直接创建一个幻引用,而必须通过像引用队列登记的途径来创建它。
 RefereceQueue aQueue = new ReferenceQueue();
 PhantomReference sRef = new PhantomReference(new SomeObject(),aQueue);

*************************************************************************************
内存泄漏的根源
第一种 几种特定的模式下,JAVA特别容易出现内存泄漏。
第二种 与Listener模式有关。如果在集合中增加了一个Listener,却没有在不需要的时候删除,结果就可能引起内存泄漏。因为集合会一直保持对Listener的引用,因此Listener不会被回收掉。
第三种情况与数据结构有关。由于大部分数据结构以某种类型的集合来存储数据,当这些数据结构生命很长,实现又不恰当,就会产生内存泄漏。
public Object pop(){
 if(top = -1)
 throws new EmptyStackException();
 Object temp = stack[top];
 stack[top] = null;//缺少则内存泄漏
 top--;
 return temp;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值