java之jvm内存结构
java内存结构
引至:https://blog.csdn.net/Prior_SX/article/details/123463430
几点说明
1、本地方法栈是java用来管理本地方法的调用的,线程私有。并不是所有jvm都支持本地方法栈,如Hotspot JVM版本,直接将本地方法栈和虚拟机栈进行了合二为一。
2、堆中年轻代的垃圾收集叫Minor GC;堆中年老代的垃圾收集叫Major GC;整个堆收集叫Full GC;整个新生代和部分老年代手机是混合GC Mixed GC(目前仅G1有)。
3、不管是 JDK8 之前的永久代,还是 JDK8 及以后的元空间,都可以看作是 Java 虚拟机规范中方法区的实现,Java 虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫 Non-Heap(非堆),目的应该是与 Java 堆区分开。
4、之前永久代受垃圾收集器管理,内存上与新生代老年代连续;jdk8之后的元数据空间存于堆外内存,不受垃圾收集器管理,比较难OOM,通过-XX:MetaspaceSize 和 -XX:MaxMetaspaceSize 用来设置元空间参数,由Java虚拟机的元空间管理器。
5、默认情况下,初始堆大小为电脑内存的1/64;最大堆内存大小为电脑内存的1/4。(建议设置成一样,回收完内存,不用重新分隔计算堆大小)。
6、方法中使用局部变量,虚拟机在运行时采用逃逸分析,有助于:栈上分配内存(对象,局部变量表中)、同步忽略、标量替换(对象替换成原始类型变量)。
7、逃逸分析在运行时对代码进行优化的一项技术,它通常在即时编译(Just-In-Time Compilation,JIT)阶段进行;但是逃逸分析技术并不是十分成熟,有性能损耗,最差情况,分析后没有逃逸的对象;不过他还是一个十分重要的优化手段。
8、元空间存储类的元信息,静态变量和常量池等并入堆中。相当于永久代的数据被分到了堆和元空间中。
9、-XX:MetaspaceSize设置元空间大小,默认64位服务器大概21M,不足的话会进行full,再根据GC情况冬天调整,不超过-XX:MaxMetaspaceSize(默认-1)
10、字符串常量池(全局字符串池)里的内容是在类加载完成,经过验证,准备阶段之后在堆中生成字符串对象实例,然后将该字符串对象实例的引用值存到string pool中,数据结构是个StringTable(记住:string pool中存的是引用值而不是具体的实例对象,具体的实例对象是在堆中开辟的一块空间存放的);而运行时常量池其实是当类加载到内存中后,jvm就会将class常量池中的内容存放到运行时常量池中,里面放的也是符号引用和字面量。JDK8后字符串池在堆中,运行时常量池在元空间(方法区)。