好处:
跨平台
内存管理机制,垃圾回收功能
数组下标越界检查
多态
名词解释:
jvm java虚拟机,是java程序的运行环境
jre jvm+基础类库
jdk jre+编译工具
javase jdk+ide工具
javaee javase+应用服务器
jvm的内存结构:
程序计数器:
java源代码-->jvm指令--解释器-->机器码-->cpu
寄存器,记住下一条jvm指令的地址
程序计数器是线程私有的,而且没有内存溢出
虚拟机栈:
每个线程运行所需要的内存,由栈帧组成,一个栈帧就是一次方法的调用,栈帧是每个
方法运行时需要的内存,每个线程只能有一个活动的栈帧,就是正在执行的那个方法
本地方法栈:
一些方法用native修饰表明方法的实现是用C语言或者其他语言实现的,不是用java实现
的。
堆:
通过new关键字创建的对象都会使用堆内存,堆是线程共享的,有垃圾回收机制。
字符串常量池。自java8开始,StringTable在堆里,
方法区:
是堆的一部分,所以方法区是内存共享的。java8后取而代之的是元空间,++运行时常量池++
和++静态常量池++ 存放在元空间里,占用操作系统的内存,++字符串常量池++依然存放在堆里。
字符串常量池用hashTable结构,
栈问题:
1、垃圾回收机制是否会回收栈内存?
不会,垃圾回收是回收堆里面的内存对象。栈内存不需要回收,因为方法结束后栈内存
就自己释放掉了。
2、栈内存分配越大越好吗?
不是,栈内存越大会导致线程数越少
3、方法内的局部变量是否线程安全?
不一定,如果变量没有逃离方法的作用范围,那就是线程安全的,反之就不是线程安全
的(方法参数,方法返回值,局部变量引用了对象),。栈是线程私有的,static变量是
在堆中的就不是线程安全的了。
栈内存溢出的原因:
方法栈帧过多(方法递归)
方法栈帧过大(方法的局部变量太多)
新生代:老年代:
永久代:使用jvm的堆的内存。java8之后,取消了整个永久代区域,取而代之的是元空间。
元空间:使用操作系统的内存,++运行时常量池++ 和++静态常量池++。
直接内存:操作系统的内存
垃圾回收: