谈谈java的内存模型
来源:互联网 发布:金十数据日历桌面 编辑:程序博客网 时间:2024/05/21 17:22
1. jvm
java中负责管理内存和垃圾回收等工作的东西:jvm我们称之为java虚拟机。简单来讲,就是jvm帮你管理你的内存分配与回收,不需要你去像c++中一样需要自己delete内存。
需要注意的几点:
1. jvm只负责与内存相关的资源的管理,其他的不属于jvm的范畴,需要你自己去控制。
e.g.文件的读取操作中流的开启和关闭、数据库连接的释放等等,这些jvm不会管理,需要你自己显式地控制,否则会出现资源消耗的情况,最终导致系统崩溃。方法是:可以在finally块中显式地释放,无论如何finally块都会在内存资源被jvm回收之前获得执行,当然,这并不意味着可以明确gc的执行时间,gc是不能被程序员控制的!
2. 有了jvm的管理内存泄露的情况依然有可能会发生
很多初学者认为java自己管理gc,那么完全不必要担心内存泄露的情况发生,这是完全错误的认识。
我们看下面的一段模拟出栈的pop代码就发生了内存泄露:
public class Stack {Object[] stack;int top;public void pop(){top--;}}虽然top--之后我们不能再访问到已经被pop的元素,但是由于实际的对象仍然在stack数组中保存了引用,因此不会被gc回收,这样这段内存就处于这种状态:访问不到也不能回收,这就是内存泄露;一次两次是没有问题,但是当调用的次数很多的时候,内存会被一点一点得耗尽,直到系统崩溃。
正确的做法是:将stack数组的该引用指向null,让gc在随后回收实际的对象
public void pop(){stack[top] = null;top--;}
2. 堆和栈
jvm将java中的基本类型变量和对象的存储分为两个区域:堆区和栈区。
a. 栈区:
存放函数的临时变量,包括java的基本数据类型变量和指向对象的引用变量(这个比较难理解,说白了就是new对象的时候等号前面的那个变量)
b. 堆区:
存放java中的实际的对象(包括数组,数组也是一种对象,显然创建一个数组也是通过new出来的)。堆区对于程序员是不透明的,jvm不允许程序员直接访问堆区中的对象,而只能通过栈区中的引用对象通过引用的方法访问实际的对象,即从栈区的引用变量有一个指向堆区中的实际对象的“指针“。
jvm为什么要设立栈区和堆区之分?
这个问题我的理解是:
1. 为了效率(efficiency)。jvm的内存管理其实基于这样的一个事实:java程序的大部分对象或者变量都是短命的(即仅仅处于年轻代),而只有少量的对象或变量会进入持久代,还有极少数的对象生命周期更长,进入到了老年代。因此,设立栈区存放那些临时变量和基本数据类型,而在堆区中的对象则会进一步分成年轻代、持久代、老年代等,用不同的策略来实行高效的gc。
2. 为了安全。众所周知,c++中的指针式初学者的一个难题,很多有经验的码农遇到指针依然会出错。由于c++不是很熟,所以不能做过多的评价,不过记得空指针和野指针的问题应该是c++中的很容易出现的问题。在java中,通过引用变量的方式避免了类似的问题的发生,jvm拒绝程序员直接访问堆区中的对象,而必须通过栈区中的引用变量访问。
3. gc的机制
简单理解就是:引用标记算法,即gc计算堆中的对象是否有指向它的引用,如果有,那么就不会回收这个对象,否在就将对象放入到待回收区域,等待回收。如果在回收执行之前,对象又被重新引用了,那么它又会重新进入活动对象区,不会被回收了。
首先从stack和静态分配区的ref查找heap中对应的对象,如果没有ref就回收它
我们来看一个例子:
class X2{ public X2 x; public static void main(String[] args){ X2 x2=new X2(); X2 x3=new X2(); x2.x=x3; x3.x=x2; x2=new X2(); x3=x2; doComplexStuff();}}after line 9 runs,how many objects are eligible for garbage collection?A.0 B.1 C.2 D.3 E.4
在第8行之前,它的内存模型是这样的:
在第9行之后,它的内存模型变为:
于是之前的两块内存空间不再有ref,可以被gc了,所以答案应该是C:2个。
- 谈谈java的内存模型
- JAVA的内存模型
- java的内存模型
- Java的内存模型
- java的内存模型
- java的内存模型
- 谈谈Java内存管理
- 谈谈Java内存管理
- 谈谈Java内存管理
- 谈谈Java内存管理
- JMM Java的内存模型
- Java对象的内存模型
- Java内存模型的抽象
- Java的内存模型分析
- java的线程内存模型
- Java内存模型的两张图
- java内存模型的理解
- java内存模型的理解
- 云计算平台
- Ext 2.2-2.3 Ext.ajax.request 同步请求的实现
- 二值的连通区域标记
- 串口编程
- Struts2 the Action upload file get json data
- 谈谈java的内存模型
- 经典笑话
- DIV透明层文字
- 如果你带一帮人去打群架,你是领头的,你对对方喊的第一句话是什么?
- django_blog搭建
- mysql的主从备份和双机互备实现
- Java中hashCode的作用
- Oracle数据库精讲与疑难解析(第2版)
- CSS兼容性(IE和Firefox)技巧