jvm内存区域

来源:互联网 发布:erp软件推荐 编辑:程序博客网 时间:2024/05/18 01:26
JVM运行时的数据区
1.程序计数器:当前程序所执行的字节码的行号指示器。
2.java虚拟机栈:描述的java方法的内存呢模型,每一个方法一都存有个java虚拟机栈帧,用于存储方法执行是需要用到的变量表,操作数栈,动态链接,方法的出口。其中局部变量表存有方法中需要用到的一些变量类型信息(Integer Long Double Reference),这个区域对应两种异常,一个是StackOverflowError(一般是在递归调用时,调用的层数数超过最大值) OutofMemoryError(无法申请内存)。
3.本地方法栈,这个和java虚拟机栈相似,只不过服务的对象不同,虚拟机栈服务于java方法,而本地方法栈服务于本地方法。
4.java堆,这是最大的内存块,用于存放对象实例和数组。这也是垃圾收集的主要区域。java堆可以分为老年代和新生代(这个在后再说)。
5.方法区。用于存储加载的类信息和常量,静态变量,即使编译器编译后的数据。感觉这是java堆的一部分。但是这还是不同的,java堆上的内存在不适用时要回收,而方法区一般不回收,由于不回收,一旦方法区中的东西不在使用那么就造成内存泄露。
关于方法区,可以看看下面这段代码
public class RunTimeConstantPoolOOM {

       public static void main(String [] args){
            String sb = new StringBuilder("hello" ).append("luoding").toString();
            System. out.println(sb.intern()==sb);
            
            String sb1 = new StringBuilder("hello" ).append("luoding").toString();
            System. out.println(sb1.intern()==sb1);
            
      }
}
代码的运行结果是true false,运行环境是java7.sb.intern方法的作用是如果常量池中已经有和sb相等的字符串就返回sb的引用,否则将sb复制到常量池中,所以我们在第一次调用intern方法是由于没有,所以将会复制sb的引用到常量池中,所以我们在第二次调用由于sb1.intern返回的是sb的引用,肯定sb的引用值不等于sb1;

6.运行时常量。这个是方法区的一部分。主要是class文件的版本信息和字段,方法,接口等信息。

几个JVM参数-Xms堆的最小大小,-Xmx堆的最大大小,-verbose:gc查看gc日志,-XSs栈容量,-Xmn 表示老年代分配的大小, -XX:PrintGCDetails 用于输出显示内存GC的日志,-XX:SurvivorRatio 设置Eden和Survivor的比值。-XX:PreternureSizeThreshold表示大对象的大小,如果一次要分配的内存达到这个值表示是一个大对象,那么直接进入老年代,以免新生代频繁的复制。-XX:MaxTenuringThreshold=1表示对象经历过一次回收就进入老年代,这个值是可以改版的。当然有事这个年龄市东戴判定的,只要同年龄的对象大于Survivor的一半那么这些对象就会进入老年代。HandlePromotionFailure ,担保参数。



0 0
原创粉丝点击