jvm内存模块

1;程序计数器:

     线程私有的,当处理器切换线程的时候,该线程上下文运行到哪都是根据程序技术器的值,来去获取字节码指令.一般来说计数器的值是字节码指令地址;当线程执行native方法的时候,计数器的值为null; 程序计数器这个内存模块是唯一没有内存溢出的情况的

2java虚拟机栈:

 线程私有的,存储的是栈桢,每个方法就是一个栈桢,所以栈桢包含了局部变量表,方法出口,操作数栈.其中局部变量表在编译期间,局部空大小都是已知的,除了long和double是2个其他都占一个局部变量空间(slot),而且一个栈桢的大小影响最大的是局部变量表,而变量表大小受long和double基本类型影响最大,所以当jvm设置虚拟机栈不是动态扩展的时候,栈的大小是固定的,这时候也可以说深度是固定的,如果栈桢太大那么,存的栈桢就少,换句话说就是线程的的调用链变短了,如果超出了栈的深度,抛出Stack Overflow,如果虚拟机栈设置动态扩展,如果申请不到内存抛出oom内存溢出;可以调整-xss

3,本地方法栈:

    线程私有的,虚拟机栈是为虚拟机执行java方法的时候(字节码)服务,本地方法栈是为虚拟机执行本地方法时服务的;不同的虚拟机对本地方法使用的语言数据结构没有严格规定,也就是都可以随意实现,sun hotspot, 就把虚拟机栈和本地方法栈合二为一;也就是也会抛出Stack Overflow和oom错误;

4堆:

  线程共享的,堆空间主要是存储的对象,当然随着技术 的发展,不是所有的对象创建都会放在堆内存;堆也是gc的主要内存块;内存参数-xmx;-xms

5,方法区:

线程共享的,主要存储类的信息,常量,静态变量,即时编译后的代码(如jsp);Hotspot把方法区作为永久代;这样gc也可像对一样回收方法区;

在JDK8之前的HotSpot实现中,类的元数据如方法数据、方法信息(字节码,栈和变量大小)、运行时常量池、已确定的符号引用和虚方法表等被保存在永久代中,32位默认永久代的大小为64M,64位默认为85M,可以通过参数-XX:MaxPermSize进行设置,一旦类的元数据超过了永久代大小,就会抛出OOM异常。

虚拟机团队在JDK8的HotSpot中,把永久代从Java堆中移除了,并把类的元数据直接保存在本地内存区域(堆外内存),称之为元空间。
把永久代从Java堆中移除了,并把类的元数据直接保存在本地内存区域(堆外内存)。这样做有什么好处?
对永久代的调优过程非常困难,永久代的大小很难确定,其中涉及到太多因素,如类的总数、常量池大小和方法数量等,而且永久代的数据可能会随着每一次Full GC而发生移动。

而JDK 1.8 的对 JVM 架构的改造将类元数据放到本地内存中,另外,将常量池和静态变量放到 Java 堆里(方法区放到了堆的永久代),类的元数据保存在本地内存中,元空间的最大可分配空间就是系统可用内存空间,可以避免永久代的内存溢出问题,不过需要监控内存的消耗情况,一旦发生内存泄漏,会占用大量的本地内存。


6 运行时常量池;

  class文件中除了类,字段方法,等还有常量池用于编译期各种符号引用等,在类加载后,会把其加到方法区的常量池中,当然运行时期也会有常量加入到常量池中,如string类的intern()方法;当内存不足也会抛出oom;

7,直接内存;

    不是java定义的内存分配,但也经常使用,在java.nio中引入了channel和buffer的io方式;直接使用native方法分配对外内存,然后通过对java的directbytebuffer直接操作这块内存.这样避免了java堆和native堆来回复制,某些场景下,显著的提高了效率


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值