精华内容
下载资源
问答
  • 一:操作系统的内存分配策略操作系统的内存分配策略主要分为三种静态内存分配内存分配内存分配静态内存分配静态内存分配是在程序编译时就能够确定的每个数据的在运行时所需的内存空间。这种分配策略不允许程序...

    一:操作系统的内存分配策略

    操作系统的内存分配策略主要分为三种

    静态内存分配
    栈内存分配
    堆内存分配

    静态内存分配

    静态内存分配是在程序编译时就能够确定的每个数据的在运行时所需的内存空间。这种分配策略不允许程序中有可变的数据结构,也不允许有递归或嵌套结构出现。

    栈内存分配

    即动态内存分配,通过栈来实现。在动态内存分配方案中,程序对数据区的需求在编译时是完全未知的,直到运行时才知道,但是规定程序在运行中进入一个程序模块时,必须知道该程序模块所需的数据区内存大小才能够为其分配内存。栈式内存分配按照先进后出的原则进行内存分配。

    堆内存分配

    只有到程序运行到相应的代码是才知道内存分配空间的大小,就需要使用堆内存分配策略。

    二:java的内存分配

    jvm的内存分配主要是基于堆和栈的内存分配

    1):栈内存分配

    栈内存分配和java线程绑定,每创建一个线程是,java就会创建一个与之对应的java栈。线程的方法调用对应java栈的压栈和出栈。每一个java方法对应一个栈帧。帧用来保存当前方法的参数,局部变量,中间计算过程和其他数据。
    栈中主要存放基本类型数据和对象引用。

    2):堆内存分配

    java堆中存放应用程序运行时创建的所有类的实例或数组。java在创建一个对象是,在堆中分配该对象的存储空间,在栈中建立一个指向这个对象的指针(引用)。java堆是一个运行时数据区,内存空间的回收由GC负责。

    展开全文
  • JVM内存分配规则

    2020-12-01 16:55:24
    JVM内存分配规则 堆内存分配: JDK8 默认的,新生代(Young)与老年代的比例值为 1:2(该值可以通过参数 -XX:NewRatio来指定)。 新生代分为 Eden和两个Survior区域,分别被命名为from和to,以示区分。 默认的,...

    JVM内存分配规则

    堆内存分配:

    JDK8 默认的,新生代(Young)与老年代的比例值为 1:2(该值可以通过参数 -XX:NewRatio来指定)。

    新生代分为 Eden和两个Survior区域,分别被命名为from和to,以示区分。

    默认的,Eden:from:to = 8:1:1(可以通过参数-XX:SurvivorRatio来设定)。

    JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;

    JVM最大分配的内存由-Xmx指 定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。

     

    非堆内存分配:

    -XX:PermSize 256MB

    -XX:MaxPermSize 256MB

    JVM使用-XX:PermSize来设置非堆内存初始值,默认是物理内存的 1/64

    由-XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4

    非堆内存分为

    Perm Gen 永久代

    JVM Stack Java 虚拟机栈

    Local Method Stack 本地方法栈

     

    举个例子

    初始设置-Xms=512MB后 JVM内存分布如下所示:

    Young 年轻代默认大小大概为 170MB

    Tenured 老年代默认大小大概为 340MB

    新生代中 Eden的默认大小为 136MB

    Survivor区的默认大小为 34MB

    To 和 From区的默认大小为 17MB

    当Eden区的对象经过15次的MInor GC后晋升到老年代

     

    对象提升(Promotion)规则

    1. 对象优先分配在 Eden 区

    2. 大对象直接进入老年区

    3. 长期存活的对象进入老年代

    4. 动态判断对象年龄

     

    展开全文
  • 一、java堆的基本分配规则 1. -对象主要分配在新生代的Eden区 ...-Xms20M jvm初始内存 -Xmx20M jvm最大内存 -Xmn10M jvm年轻代大小 这三个参数限制了java堆大小为20MB不可拓展,其中10MB 分配给新生代...

    一、java堆的基本分配规则

    1.
    -对象主要分配在新生代的Eden区
    -如果启动了本地线程分配缓冲,按线程优先在TLAB上分配
    -少数情况下也可能直接分配在老年代中,比如较大的对象

    2.GC参数指定垃圾回收
    -Xms20M   jvm初始内存
    -Xmx20M   jvm最大内存
    -Xmn10M   jvm年轻代大小
    这三个参数限制了java堆大小为20MB不可拓展,其中10MB
    分配给新生代,剩下的10MB分配给老年代,一般我们将新生代老年代比列设置为为1:2
    -Xx:SurvivorRatio=8决定了新生代中Eden区与两个Survivor区的
    空间比例为8:1

    3.
    新生代GC(MinorGC) :发生在新生代的GC
    老年代GC(MajorGC或者FullGC)
    一般情况下,MajorGC比FullGC慢10倍以上

    测试代码:

    /**
     * @Auther: jorian
     * @Date: 2019/7/31 21:16
     * @Description:
     */
    public class JvmTest01 {
        private static final int bsize = 1024*1024;
        public static void main(String []args){
            byte[] b =new byte[40*bsize];
        }
    }

    配置启动参数: -verbose:gc -XX:+PrintGCDetails

    可以看到使用的parllel scavenge的垃圾收集器


    我们也可以指定使用串行的serial垃圾收集器: -verbose:gc -XX:+PrintGCDetails -XX:+UseSerialGC

    可以看到,垃圾收集器已被修改,def就是指serial垃圾收集器

    结论:基本分配原则:对象初始分配一般在新生代的Eden区

    二、大对象的分配规则

    -所谓的大对象是指需要大量连续内存空间的java对象,最典型的大对象就是那种很长的字符串
    以及数组
    -虚拟机提供了一个-XX:PretennureSizeThreshold参数,令大于这个设置值的对象直接在老年代分配
    这样避免了在新生代的Eden和Survivor区发生较大的内存复制

    代码测试:

    /**
     * @Auther: jorian
     * @Date: 2019/7/31 21:53
     * @Description:
     */
    public class JvmTest02 {
    
        public static void main(String args[]){
           byte[] bytes = new byte[1024*1024*10];//10M
        }
    }
    

    设置启动参数:
    -verbose:gc                           //开启GC日志
    -XX:+PrintGCDetails             //打印GC详情
    -XX:+UseSerialGC                 //使用SerialGC
    -XX:PretenureSizeThreshold=314728   //设置大对象阈值,超过即分配到老年代
    -Xms20M   -Xms20M  -Xmx20M  -Xmn10M
     

    启动项目,结果:可以看到,老年代正好占用了10M,说明超过我们设置的3M阈值,对象分配到了老年代

    三、逃逸分析和栈上分配

    逃逸分析:
    逃逸分析的基本行为就是分析对象的动态作用域,当一个对象在方法中被定义后,它可能被外部方法所引用
    ,称为方法逃逸,甚至还有可能被外部线程访问到,比如赋值给类变量或可以在其他线程中访问的实例变量
    ,称为线程逃逸

    栈上分配:
    栈上分配就是把方法中的变量和对象分配到栈上,方法执行完后自动销毁,而且不需要垃圾回收的介入
    从而提高系统性能。

    栈上分配演练:代码:

    /**
     * @Auther: jorian
     * @Date: 2019/7/31 22:18
     * @Description:
     */
    public class TestEscape {
    
        public static Object obj;
        public void variableEscape(){
            obj = new Object();  //发生逃逸
        }
    
        public Object methodEscape(){
            return new Object();//方法逃逸,不在方法里面了
        }
    
        public static void alloc(){
            byte[] bytes = new byte[2];
            bytes[0] = 1;
        }
    
        public static void main(String args[]){
            Long start = System.currentTimeMillis();
           //分配1000万次
            for(int i = 0; i < 100000000; i++){
                alloc();
            }
            Long end = System.currentTimeMillis();
            System.out.println(end-start);
        }
    
    }
    

    设置jvm启动参数,关闭jdk1.8默认开启的逃逸分析:-XX:-DoEscapeAnalysis

    启动程序:可以看到时间为47

    修改jvm启动参数,加上逃逸分析,-XX:+DoEscapeAnalysis

    可以看到时间大幅缩小,时间为:15

    如果开启了逃逸分析,就会进行栈上分配。
    关闭逃逸分析,打开gc日志:

    启动程序,发生了频繁的yongGC!!原因是内存不够分配。 

     

     

     

     

    展开全文
  • JVM 内存分配策略

    2018-12-27 13:42:17
    在操作系统中将内存分配策略分为三种,分别是: 1) 静态内存分配 2) 栈内存分配   3) 堆内存分配   静态内存分配是指在程序编译时就能确定每个数据在运行时的存储空间需求,因此在编译时就可以给它们分配固定...

    在操作系统中将内存分配策略分为三种,分别是:
    1) 静态内存分配
    2) 栈内存分配

     

    3) 堆内存分配

     

    静态内存分配是指在程序编译时就能确定每个数据在运行时的存储空间需求,因此在编译时就可以给它们分配固定的内存空间。这种分配策略不允许在程序代码中有可变数据结构(如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编
    译程序无法计算准确的存储空间需求。


    栈式内存分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的。和静态内存分配相反,在栈式内存方案中,程序对数据区的需求在编译时是完全未知的,只有到运行时才能知道,但是规定在运行中进入一个程序模块时,必须知道该程序模块所需的
    数据区大小才能够为其分配内存。和我们所熟知的数据结构中的栈一样,栈式内存分配按照先进后出的原则进行分配。

     

    堆这种分配策略是当程序真正运行到相应代码时才会知道空间大小,在这种情况下我们就需要堆这种分配策略,堆分配策略是最自由的,但是这种分配策略对操作系统和内存管理程序来说是一种挑战。另外,这个动态的内存分配是在程序运行时才执行的,它的运行效率也是比较差的

    Java 中的内存分配详解

    JVM 内存分配主要基于两种,分别是堆和栈。

    Java 栈的分配是和线程绑定在一起的,当我们创建一个线程时,很显然,JVM 就会为这个线程创建一个新的Java 栈,一个线程的方法的调用和返回对应于这个Java 栈的压栈和出栈。当线程激活一个Java 方法时,JVM 就会在线程的Java 堆栈里新压入一个帧,这个帧自然成了当前帧。在此方法执行期间,这个帧将用来保存参数、局部变量、中间计算过程和其他数据。栈中主要存放一些基本类型的变量数据(int、short、long、byte、float、double、boolean、char)和对象句柄(引用)。存取速度比堆要快,仅次于寄存器,栈数据可以共享。缺点是,存在栈中的数据大小与生存期必须是确定的,这也导致缺乏了其灵活性。

     

    从堆和栈的功能和作用来通俗地比较,堆主要用来存放对象,栈主要用来执行程序,这种不同主要是由堆和栈的特点决定的。

    堆在应用程序运行时请求操作系统给自己分配内存,由于操作系统管理内存分配,所以在分配和销毁时都要占用时间,因此用堆的效率非常低。但是堆的优点在于,编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要在堆里停留多长时间,因此,用堆保存数据时会得到更大的灵活性。事实上,由于面向对象的多态性,堆内存分配是必不可少的,因为多态变量所需的存储空间只有在运行时创建了对象之后才能确定。在C++中,要求创建一个对象时,只需用 new 命令编制相关的代码即可。执行这些代码时,会在堆里自动进行数据的保存。当然,为达到这种灵活性,必然会付出一定的代价——在堆里分配存储空间时会花掉更长的时间

     

    展开全文
  • jvm内存分配机制

    2019-11-02 18:00:22
    jvm内存分配原则 1、对象优先在Eden区分配 大多数情况下,对象在新生代中的Eden区分配,当Eden区没有足够的空间进行分配是,虚拟机将发起一次Minor GC。 Minor GC和Full GC的区别: Minor GC/Young GC: 发生在...
  • JVM内存分配及GC详述

    2019-01-02 08:49:54
    在阐述JVM内存区域之前,先来看下计算机的存储单位。从小到大依次为Bit,Byte,KB,MB,GB,TB。相邻的单位相差2的10次方。  计算机运行中的存储元件主要分为寄存器(位于CPU)和内存,寄存器和内存之间通过地址...
  • 图解JVM 内存分配

    2012-09-21 22:31:08
    现摘录一段Java5内存管理白皮书中的一段话: One strength of the Java™ 2 Platform,Standard Edition (J2SE™) is that it performs automatic memory management, thereby shielding the developer from the ...
  • 二、简单了解jvm内存和gc 在此之前,我们应该对jvm的内存分配,以及基本的gc机制有一定的了解。 简单说,jdk8以后,堆区就分为新生代和老年代,图中的Permanent永久代被移除了,用元空间代替。 默认的,新生代 ( ...
  • 深入理解JVM之JVM内存区域与内存分配  在学习jvm的内存分配的时候,看到的这篇博客,该博客对jvm的内存分配总结的很好,同时也利用jvm的内存模型解释了java程序中有关参数传递的问题。  博客出处: ...
  • JVM 内存分配模型概念 --在工作中可能用到的机会不多,有个概念的了解 --此文是转载某位读者,应该是在阅读了《深入理解Java虚拟机JVM高级特性与最佳实践》 一书后,总结所得。写的不错,转载哈 一、JVM内存区域...
  • JVM 内存分配模型概念 --在工作中可能用到的机会不多,有个概念的了解 --此文是转载某位读者,应该是在阅读了《深入理解Java虚拟机JVM高级特性与最佳实践》 一书后,总结所得。写的不错,转载哈 一、JVM内存区域...
  • JVM 内存模型 内存分配JVM

    千次阅读 2016-05-20 23:51:47
    1.了解 Java 虚拟机内存模型 2.揭开 Java 对象内存分配的秘密 3.Java 虚拟机的锁优化策略 &gt; Java内存管理与内存模型 Java内存管理- ...
  • 新创建的对象被分配到Eden Space区,Eden Space区内存不足就会触发MinorGC清理Eden Space内存。这个区域(新生代)的对象都是朝生夕死,是对象最频繁发生的区域。 大对象直接进入老年代 需要大量连续空间的对象...
  • 内存分配策略 分配原则 优先分配到Eden 大对象可能直接被分配到老年代  为什么大对象直接被分配到老年代? 答:大对象一般是大的字符串或数组,大对象一般都不是朝生夕死的,它的存活时间比较长。...
  • 前言:这是一篇关于JVM内存区域的文章,由网上一些有关这方面的文章和《深入理解Java虚拟机》整理而来,所以会有些类同的地方,也不能保证我自己写的比其他网上的和书本上的要好,也不可能会这样。写博客的目的是...
  • JVM运行内存分配和回收

    千次阅读 2018-09-11 09:16:20
    本文来自网易云社区作者:吕宗胜Java语言与C语言相比,最大的特点是编程人员无需过多的关心Java的内存分配和回收,...所以对于Java程序员来说认识和了解JVM内存分配和回收对于代码的编写和应用的优化都有非常重要...
  • 原文于2008年11月13日 发表, 2008年12月18日...学C/C++出身的我,对Java有一点非常困惑,那就是缺乏计算对象占用内存大小的机制。而在C++中就可以通过sizeof运算符来获得基本类型以及类实例的大小。C和C++中的这个操作
  • 1、大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC 2、大对象直接进入老年代。大对象指需要大量连续内存空间的Java对象,最典型的大对象就是那种很长的字符串...
  • JVM内存

    千次阅读 2016-03-28 20:02:58
    下面有关JVM内存,说法错误的是?正确答案: C A.程序计数器是一个比较小的内存区域,用于指示当前线程所执行的字节码执行到了第几行,是线程隔离的 B.Java方法执行内存模型,用于存储局部变量,操作数栈,动态链接...
  • JVM内存模型和JVM内存结构

    千次阅读 2019-05-20 16:03:05
    Java内存模型(即Java Memory Model,简称JMM)本身是一种抽象的概念,并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问...
  • JVM内存结构

    2017-02-13 16:19:42
    主要内容如下:JVM启动流程 JVM基本结构 内存模型 编译和解释运行的概念  ...Java中的内存分配: Java程序在运行时,需要在内存中的分配空间。为了提高运算效率,就对数据进行了不同空间的划分,因为每一片区域都有特
  • JVM内存详解

    2019-03-22 13:53:40
    下面有关JVM内存,说法错误的是? A:程序计数器是一个比较小的内存区域,用于指示当前线程所执行的字节码执行到了第几行,是线程隔离的。 B:虚拟机栈描述的是Java方法执行的内存模型,用于存储局部变量,操作数...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 44,277
精华内容 17,710
关键字:

jvm内存分配原则