选择javase知识点,jvm内容之一内存分配管理。
java虚拟机的介绍
jvm是java底层的虚拟机,作用不言而喻,java的跨平台,可移植,不就是jvm的功劳么?下面这个图是jvm内存分配的全局:
分析如下:
什么是java堆?
1.堆的定义
java堆是java虚拟机管理的内存最大的一块,被所有线程共享一块内存区域,在虚拟机启动时候创建。唯一目的是存放对象实例,机会所有的对象实例都在这里分配
内存。
2.堆的大小调节
大致分为2中情况:
1.JVM中堆空间可以分成三个大区,新生代、老年代、永久代
2.新生代可以划分为三个区,Eden区,两个幸存区
1.JVM运行时堆的大小
-Xms堆的最小值
-Xmx堆空间的最大值
2.新生代堆空间大小调整
-XX:NewSize新生代的最小值
-XX:MaxNewSize新生代的最大值
-XX:NewRatio设置新生代与老年代在堆空间的大小
-XX:SurvivorRatio新生代中Eden所占区域的大小
3.永久代大小调整
-XX:MaxPermSize
4.其他
-XX:MaxTenuringThreshold,设置将新生代对象转到老年代时需要经过多少次垃圾回收,但是仍然没有被回收
*所有的对象不一定都是分配到堆上面的,JIT编译器的发展与逃逸分析技术的逐渐成熟,可以达到到栈上分配对象的实例。
什么是java方法区?
方法区与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机,加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
什么是PC寄存器?
是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器,在虚拟机的概念模型里,字节码解析器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
什么是本地方法栈?
本地方法栈是一虚拟机所发挥的作用是非常相似的,之间的区别不过是虚拟机栈为虚拟机执行java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。在虚拟机规范中对本地方法栈中方法使用的语言、使用方式与数据结构并有没强制规定,因此具体的虚拟机可以自由实现它。甚至有的虚拟机直接就把本地方法栈和虚拟机栈合二为一,与虚拟机栈一样,本地方法栈区域也会抛出StackOcerflowError和OutOfMemoryError异常。
什么是java栈?
java栈也与程序计数器一样,是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直执行完成的过程,就对应着一个栈帧在虚拟机中入栈道出栈的过程。
调节java栈的参数配置方式例如如下:
-Xss128k
java几种异常的案例
1.java堆异常
参数配置:
-Xms5M
-Xmx10M
public static void main(String[] args) {
List<byte[]> list = new ArrayList<byte[]>();
for (int i = 0; i < 50000; i++) {
byte[] ch = new byte[1024];
list.add(ch);
}
System.out.println("over");
}
异常信息:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at com.lgy.test.MyTEST.main(MyTEST.java:11)
参数配置调大后并不在有异常信息。
2.java栈异常
参数配置:
-Xss5M
public class Test1 {
private int i = 0;
public static void main(String[] args) {
Test1 test = new Test1();
try {
test.fun();
} catch (Error e) {
System.out.println(test.i);
}
}
public void fun() {
i++;
fun();
}
}
异常信息:java.lang.StackOverflowError
通过配置不同-Xss的大下,得到的堆栈的深度是不同的。
public class Test1 {
private int i = 0;
public static void main(String[] args) {
final Test1 t = new Test1();
while (true) {
new Thread(new Runnable() {
@Override
public void run() {
t.fun();
}
}).start();;
}
}
public void fun() {
while(true){
}
}
}
由于多线程直接映射到内核,系统会堵塞,注意此时会抛出: java.lang.OutOfMemoryError
jvm几块区域对于数据的使用划分
1.几片区域对于运行数据区的关系
2.栈对于运行数据区的关系
3.堆对于运行数据区的关系