2018-12-07

运行时数据区

虚拟机栈

本地方法栈

方法区

虚拟机栈:线程私有。其实就是记录方法的一个栈,每次方法执行的时候就会往里面push一个栈帧。一个方法的生命历程就是在虚拟机栈里面入栈到出战的过程。每一个栈帧里面有方法的局部变量表和操作数栈,动态链接,以及方法出口。一般说的栈内存就是指的这一区域,或者是他局部变量表部分,局部变量表里面存放的是各种基本类型,和对象的引用类型ref,值得一提的是局部变量表的长度或者是大小是不会变得,运行时不会改变,不知道是怎么确定这个大小的???。关于stackoverflow的出现,每执行一个方法就会push一个栈帧,当写出死循环后者是无穷无尽的递归的时候,一直push而不pop就会出现stack的大小不够,就会出现stackoverflow这个异常。如果虚拟机栈是可以动态扩展的,当无法申请到内存的时候就会出现oom异常。
本地方法栈:这区和虚拟机栈一样,不同是他只为native也就是本地方法服务,也会出现两种异常。有的虚拟机实现的时候会将两个虚拟机栈合并到一起 hotspot。
方法区:线程共有,里面存放了已经被虚拟机加载的类信息,常量,静态变量,以及即使编译的代码。Non-heap,一般说的永久代就是说的这个,但是不准确,因为在之前的版本里面都是用永久代的方式去实现的方法区。这里一般不会有垃圾收集,如果是垃圾收集,一般指的是常量池的收集和类型的卸载,但是类型卸载的条件太苛刻了。当方法区无法申请内存之后会oom。
heap:内存模型里面最大的部分。存放内存的实例。里面会发生GC有FullGC和minorGC,是线程共有的,然后也会为线程分出私有的缓冲区,heap按代划分则是新生代和老年代,新生代里面有eden fromSurviver ToSurviver等三个空间。当内存不够的时候会发生oom。
程序计数器:靠这个来指挥字节码工作
运行时常量池:他是方法区的部分,放置编译的字面量和符号引用。常量池具有动态性,不仅仅可以编译的时候产生内容运行的 时候也可以将内容放进去。比如说String的intern方法。当常量池里面无法再申请内存的时候会oom。
直接内存:并不是运行时内存的一部分,在jdk1.4里面加入了NIO,能够在native方法里面直接分配堆外内存。-Xmx过大导致jvm的内存过高导致动态拓展的时候会出现oom。

heap

程序计数器

eden

Fs

F2

8:1:1

关于Intern方法,当常量池里面有这个字符串的时候,就返回这个字符串的引用。

关于string 设计成不可变的原因:
1在编程的时候大部分时间都是在处理字符串,不可变相当于是一种优化。
2安全性的考虑可以防止字符串有意无意的篡改。
3作为hash表里面的key应该是不可变的。

你可能感兴趣的:(2018-12-07)