一. 堆,栈,堆栈
1. 堆(heap):
-
堆通常是一个可以被看做一棵树的数组对象
-
堆中某个节点的值总是不大于或不小于其父节点的值
-
堆总是一颗完全二叉树
-
堆是在程序运行时申请某个大小的内存空间,而不是在程序编译时,即动态分配内存。
-
堆是指程序运行时申请的动态内存,而栈只是指一种使用堆的方法
2. 栈(stack):
-
栈又名堆栈,一种运行算受限的线性表
-
栈是操所系统在建立某个进程或者线程,为其建立的存储区域,该区域具有FIFO的特性,在编译时可以指定需要的Stack的大小
3. 堆和栈的区别:
-
堆一般由程序员分配释放,栈由操作系统自动分配释放
-
堆是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定;栈使用的是一级缓存,调用完毕立即释放
二. Java的内存
Java的JVM的内存可分为3个区:堆(heap)
、栈(stack)
和方法区(method)
1. 堆区-存放所有new出来的对象
-
存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
-
jvm只有一个堆区(heap),被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身
2.栈区-存放基本类型的变量数据和对象的引用
-
每个线程包含一个栈区,栈中只保存基础数据类型的对象(比如int i=1中1就是基础类型的对象)和对象的引用(不是对象),而真实对象都存放在堆区中
-
在JDK6.0及之前版本,字符串常量池是放在方法区中;在JDK7.0版后,字符串常量池被移到了堆中
-
每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
-
栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
-
方法不存在在堆内存中,是放在代码区,只有在调用的时候,才会构建该方法的运行时环境,包括参数,局部变量等,当然,这些也都是在栈内存中的。堆内存只存放被new出来的东西。
3.方法区
-
方法区,又名静态区,永久代;跟堆一样,被所有的线程共享
-
方法区包含所有的class和static变量(静态变量),全局变量和静态变量的存储是放在一块的
-
方法区中包含的都是在整个程序中永远唯一的元素(public static)
-
运行时常量池存放在方法区,存放基本类型常量(public static final)
-
方法区中对于每个类存储了以下数据:
1.类及其父类的全限定名(java.lang.Object)
2.类的类型(Class or Interface)
3.访问修饰符(public, abstract, final)
4.实现的接口的全限定名的列表
5.常量池
6.字段信息
7.方法信息
8.静态变量
9.ClassLoader引用
10.Class引用
4.解析
-
栈和常量池中的数据可以共享,具有多个引用对象。
-
堆中的对象不可以共享,一个引用对象。
-
栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会自动消失。
-
堆中的对象的由垃圾回收器负责回收,因此大小和生命周期不需要确定,具有很大的灵活性。
网友评论