JVM内存结构


Java堆(Heap)

线程所共享资源,主要用于存储new出来的实例对象和数组

方法区(No-Heap)
运行时常量池:类信息、常量、静态变量、即时编译器编译后的代码等数据

线程运行的内存结构

java虚拟机栈
(1)局部变量表
存储局部变量。如果是基本类型直接存储;如果是对象和数组,仅仅存储指向他们的地址,而对象和数组本身存储到堆中。

f1(){
  int i = 1;
  Date date = new Date();
  Long[] array = new Long[]{1L,2L};
}
i=1存储在局部变量表;date引用存储在局部变量表,date本身存储在堆;arrary引用存储在局部变量表,array本身存储在堆

(2)操作数栈
局部变量在运算过程中,使用的临时数据存储区域,可以看出操作数栈就是压栈和弹栈操作


(3)动态链接
指向方法所在类的常量池

(4)返回地址
并不是严格意义的结构,情况1:方法正常结束,返回一个return值给调用方;情况2:抛出异常,由调用方的异常处理模块处理

本地方法栈
和虚拟机栈类似,只不过是native方法

程序计数器
记录当前线程指令执行的位置,线程切换上下文恢复后,重新又从之前保存的位置开始执行


发生OutOfMemoryError异常
如果堆中没有内存分配实例,且堆也无法再扩展时候
当方法区无法满足内存分配需求时
当扩展虚拟机栈无法申请到足够的内存

发生StackOverflowError异常
线程请求的栈帧大于最大的栈深度。因为在java虚拟机栈中,一个方法就是一个栈,白话说就是调用太多方法

 

JVM内存结构图

堆空间细分
年轻代(New):年轻代用来存放JVM刚分配的Java对象
年老代(Old):年轻代中经过垃圾回收没有回收掉的对象将被Copy到年老代
New又分为几个部分:
默认大小比例:Eden:Survivor1:Survivor2 = 8:1:1
Eden:Eden用来存放JVM刚分配的对象
Survivor1,Survivor2:两个Survivor空间一样大,当Eden中的对象经过垃圾回收没有被回收掉时,会在两个Survivor之间来回Copy,当满足某个条件,比如Copy次数,就会被Copy到Old。显然,Survivor只是增加了对象在年轻代中的逗留时间,增加了被垃圾回收的可能性。

JVM的参数调优

-Xms设置堆的初始空间大小
-Xmx设置堆的最大空间大小

-XX:NewSize设置新生代初始空间大小
-XX:MaxNewSize设置新生代最大空间大小
-Xmn:相当于同时设置了NewSize和MaxNewSize的大小

-XX:PermSize设置永久代最小空间大小
-XX:MaxPermSize设置永久代最大空间大小

-Xss:设置每个线程的栈大小

例子:
-Xms128m
堆最初始为128M,默认为物理内存的1/64,最小为1M
-Xmx128m
堆最大值,默认为物理内存的1/4或者1G,最小为2M

-XX:MaxPermSize=256m
MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4
-XX:MaxNewSize=256m
新生成的对象,能占用内存的最大值

-XX:PermSize=256m
PermSize设置永久代内存初始值,默认是物理内存的1/64

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值