sherry技术总结-jvm内存与list数据结构

来源:互联网 发布:c语言开发工具 win10 编辑:程序博客网 时间:2024/06/01 08:33
sherry say:
JAVA内存:
Heap 堆区 --> 对象实际存放的地方
Stack 栈区 --> Thread独享,存放【1new出来的对象的引用,【2】基本类型数据
Static 常量区 --> Thread共享
 
Heap  Stack 所占空间大,所以慢,与具体实现无关
 
Array list  linked list 比较:
add:【1】寻址到最后一个元素(Array直接可以算出地址,linked list需要遍历所有节点),【2】添加元素
insert:【1】寻址到指定元素,【2】添加新元素并移动后续元素(Array的需要遍历移动,linked list只需改动prenextlink)(也可以讲Array的主要cost在于堆操作,而linked list基本都是栈操作)

--------------------------------------------------------------------------------------------------------------------------------------------

Answer:

理解堆区、栈区、常量区这些内存模型,是学习JVM虚拟机、垃圾回收,java线程的基础。
原理其实也是参照操作系统(windows、linux)设计的。
以下说的没啥问题了,记得堆区也是线程共享的。

堆区的操作会比栈区操作慢,也有很多原因了,上次没讲全,一时想不起那么多。
1 空间比栈区大得多,寻址费时,当时这是最基本的
2 堆区的内存操作同时伴随着垃圾回收,本身就很耗时,算法也复杂,比如划分新生代老年代,判断对象是否需要回收,如果是full GC,甚至整个系统都会停顿
   #垃圾回收只针对堆
3 除了对象回收即垃圾回收,对象初始化的做法也很不同,
   栈区都是个4字节的对象引用,比如程序进入了某个函数,方法内多一个引用就多push一个4字节的指针(引用)进栈,如果程序出了函数,局部变量的引用就全部弹出,很好的利用了后进先出的特性。这里也要注意,栈区的操作是利用了栈这个数据结构做的一系列内存操作。
   堆区则要在内部根据不同对象大小选择初始头地址,占用空间比较大的对象为了保证内存连续,可能还要调整其他对象的存储位置,如果新生代放不下的对象要放到老年代,新生代存在时间久了也要放到老年代等等

垃圾回收我们肯定还要另外从头讲的,但简单来说,就是当某个对象已经不使用,栈区已经把对象引用弹出去了,这时候堆区通过计数的方式,清算当前对象是否有引用,没有的就回收,通过计时的方式,如果一段时间依然存在引用,则进入老年代。
所以堆区复杂很多了吧。

list的总结已经挺到位了,理解得不错。补充下,arraylist是内存连续的,而linkedList是链式结构,散的。
insert你写的arraylist要遍历移动,我知道你的意思啦,你想表达的是后移操作,更专业的说法是内存relloc,意思是重新分配内存,因为以我们人类的思维来说这是后移,对于计算机来说,这么大块内存,每个值都重新写,并可能要扩容,对于计算机是一个relloc操作,这样的操作都比较花费时间