网站建设的总体需求是什么,o2o网站,青海省电话黄页,网站建设中如何设置外链接文章目录 1、JVM2、程序计数器3、堆4、栈4.1 垃圾回收是否涉及栈内存4.2 栈内存分配越大越好吗4.3 方法内的局部变量是否线程安全吗4.4 栈内存溢出的情况4.5 堆和栈的区别是什么 5、方法区5.1 常量池5.2 运行时常量池 6、直接内存 1、JVM
Java源码编译成class字节码后#xf… 文章目录 1、JVM2、程序计数器3、堆4、栈4.1 垃圾回收是否涉及栈内存4.2 栈内存分配越大越好吗4.3 方法内的局部变量是否线程安全吗4.4 栈内存溢出的情况4.5 堆和栈的区别是什么 5、方法区5.1 常量池5.2 运行时常量池 6、直接内存 1、JVM
Java源码编译成class字节码后JVM负责class字节码的处理。不同操作系统下的JVM将字节码处理成对应操作系统下的二进制文件从而实现一次编译到处运行。能到处运行是因为不同操作系统有不同的JVM也即编译后的class字节码和操作系统之间隔着一个JVM在干活儿。
简单的理解JVM就是Java二进制字节码的运行环境是JDK包下包含的一些代码像一个虚拟的计算机一样处理着class字节码。
JVM有两个最大的亮点
处理class字节码实现一次编译到处运行自动内存管理垃圾回收机制创建的对象用完后不用手动回收
JVM的组成 2、程序计数器
线程私有的每个线程各有一份内部保存的字节码的行号。用于记录正在执行的字节码指令的地址。 如上线程1 执行字节码从第0行到第10行后CPU时间片用完线程1的程序计数器记录下当前行号。CPU的时间片分给了线程2 线程2执行到第9行后CPU时间片用完。线程1再次抢到时间片继续执行此时根据线程1的程序计数器CPU就知道该从第10行继续往下执行。
3、堆
堆区线程共享保存着创建出来的对象use、total、maxuse max 后无法再分配空间堆内存溢出
堆中有年轻代和老年代。年轻代有三部分伊甸园区和两块大小相同的幸存者区。根据JVM策略新创建的对象在伊甸园区伊甸园区满了以后触发Young GCGC后或者的对象复制到幸存者区后面每GC一次活着的对象年龄加一对象头里存着年龄对象GC年龄到达阈值如15后晋升到老年代。 元空间里存类的信息、静态变量、常量、编译后的字节码信息InstanceKlass对象c。对JDK7和8其位置变化
JDK7及以前方法区在堆区的永久代空间里JDK8及以后永久代被移除用元空间代替方法区在元空间而元空间在操作系统的直接内存里理论上可以一直分配 因为永久代/方法区或者说后来的元空间存储的主要是一些类信息和常量需求开发加载的类越来越多这个空间不可控移除永久代在本地内存放个元空间可以防止OOM
4、栈
栈即每个线程运行时需要的内存空间保存着该线程方法调用的基本数据先进后出其中每一个调用的方法用一个叫栈帧的东西存。 4.1 垃圾回收是否涉及栈内存
垃圾回收处理的主要是堆内存对于栈内存栈帧弹栈后内存就会释放
4.2 栈内存分配越大越好吗
默认1024k栈帧过大会导致线程数变少机器总内存为512m目前能活动的线程数则为512个如果把内存改为2048k则可活动的线程数上限在栈内存方面就会减半
4.3 方法内的局部变量是否线程安全吗
在方法的作用范围之内是线程安全的。出了方法被怎么使用就不一定了。如下 每个线程过来都会在自己的栈里创建一个m1方法对应的栈帧栈帧里存着局部变量sb因此线程安全。
对m2方法来说局部变量sb是传过来的那可能就有线程安全问题如上面main线程中在操作sb新开的一个线程也在操作sb。同理m3方法将局部变量sb return后面可能被一个成员变量接收但后面本质上也不关局部变量的事了
4.4 栈内存溢出的情况
栈帧过多导致栈内存溢出如递归调用
public static void m1() {m1();
}栈帧过大导致栈内存溢出
4.5 堆和栈的区别是什么
栈内存一般会用来存储局部变量和方法调用但堆内存是用来存储Java对象和数组的堆会GC垃圾回收而栈不会栈内存是线程私有的而堆内存是线程共有的两者异常错误不同但如果栈内存或者堆内存不足都会抛出异常栈空间不足Java.ang.StackOverFlowError堆空间不足java.lang.OutOfMemoryError.
5、方法区
方法区和堆一样各个线程共享主要存储类的信息InstanceKclass对象、运行时常量池虚拟机启动的时候创建虚拟机关闭的时候释放方法区的内存空间不够时抛异常OutOfMemoryErrorMetaspace方法区是一个概念不同版本的JDK有不同的实现对JDK7来说永久代是其对方法区的落地实现且此时永久代在堆区对JDK8来说则给方法区换了一种实现元空间元空间在本地内存 5.1 常量池
javap查看一个类是字节码的结构信息可以看到类的基本信息、常量池、方法的定义 常量池可以看作是一张表虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息 5.2 运行时常量池
上面提到常量池是class文件中的当这个类被加载它的常量池信息就会放入到运行时常量池并发里面的符号地址变为真实地址 常量池和运行时常量池的区别 【区别】
6、直接内存
直接内存操作系统分给JVM进程的内存之外的内存不属于JVM内存不由JVM进行管理。在进行NIO操作时用于数据缓冲区其分配回收成本高但读写性能好。常规IO复制文件流程 NIO复制文件流程这块直接内存系统和Java代码都可以直接访问少了一次缓冲区的复制操作 直接内存主要通过 java.nio 包下的 ByteBuffer 类来进行分配和使用。
ByteBuffer.allocateDirect(int capacity)直接内存可以减少数据在 Java 堆和操作系统内存之间的拷贝次数从而提高 I/O 的效率常用于文件读写
【相关】