水下功夫做透,水上才能顺风顺水。

JVM内存模型

一. JVM内存结构图(JDK1.6)

 

pc(程序计数器):保存当前线程正在执行的字节码的行号,线程私有;
JVM栈:栈里面存放着方法的基本数据类型和对象的引用,线程私有;

 

 

 

 

局部变量表:方法中定义的局部变量都会存放在局部变量表。
​操作数栈:操作数栈将变量之间的运算入栈,存储计算结果,再出栈赋值给局部变量表
方法出口:方法出口记录了test()方法执行完成后的一个出口,也就是回到main()。


本地方法栈:本地方法供java直接调用本地 C/C++ 库方法,线程私有;

 

 

:存放new出来的对象和数组,是垃圾回收区域,线程共有;
方法区:用于存储被虚拟机加载的类信息、常量和static变量,线程共有。

二. JVM 内存模型(JDK1.7)

永久代仍存在于JDK1.7中,并没完全移除,譬如符号引用(Symbols)转移到了native(本地) heap;字面量(interned strings)+类的静态变量(class statics)转移到了java heap,类的加载信息还在永久代中。

三. JVM内存结构图(JDK1.8)

因此,默认情况下,元空间的大小仅受本地内存限制,但可以通过以下参数来指定元空间的大小。

JDK8中JVM不再有方法区,方法区存储的信息:1、类信息->元数据区  2 、static变量+常量池->jvm堆中。元数据空间不在jvm中,而是使用本地内存(jvm之外的内存,但也有可能被java使用)。

为什么要移除永久代?

答案一

    1、由于Permanent Generation内存经常不够用或发生内存泄露,引发恼人的java.lang.OutOfMemoryError: PermGen 。
 2、移除Permanent Generation可以促进HotSpot JVM与JRockit VM(甲骨文的虚拟机)的融合,因为JRockit没有永久代。
 3、对永久代进行调优是很困难的。

答案二

 1、字符串存在永久代中,容易出现性能问题和内存溢出。
 2、类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。
 3、永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。
 4、Oracle 可能会将HotSpot 与 JRockit 合二为一。

 JVM使用的内存可以总体划分为两部分:Heap MemoryNative Memory。前者我们比较熟悉,是供Java应用程序使用的;后者也称为C-Heap,是供JVM自身进程使用的。

posted @ 2020-05-16 07:08  北方寒士  阅读(439)  评论(0编辑  收藏  举报