精华内容
下载资源
问答
  • Java 读取tomcat使用JVM内存信息

    千次阅读 2018-06-16 10:29:48
    Java代码如下:public static void main(String[] args) {  Runtime runtime = Runtime.getRuntime();  double freeMemory = (double)runtime.freeMemory()/(1024*1024);  double totalMemory = ...

    Java代码如下:

    public static void main(String[] args) {
            Runtime runtime = Runtime.getRuntime();
            double freeMemory = (double)runtime.freeMemory()/(1024*1024);
            double totalMemory = (double)runtime.totalMemory()/(1024*1024);
            double usedMemory = totalMemory - freeMemory;
            double percentFree = (usedMemory/totalMemory)*100.0;
            System.out.println(ToolsUtils.formatTosepara(percentFree));
        }
    

    很简单,只需要将值传入前端即可查看。

    效果如上图所示

    博主也找了一份jsp中的使用方法,如下所示:

    <%  
            double total = (Runtime.getRuntime().totalMemory()) / (1024.0 * 1024);  
            double max = (Runtime.getRuntime().maxMemory()) / (1024.0 * 1024);  
            double free = (Runtime.getRuntime().freeMemory()) / (1024.0 * 1024);  
            out.println("Java 虚拟机试图使用的最大内存量(当前JVM的最大可用内存)maxMemory(): " + max + "MB<br/>");  
            out.println("Java 虚拟机中的内存总量(当前JVM占用的内存总数)totalMemory(): " + total + "MB<br/>");  
            out.println("Java 虚拟机中的空闲内存量(当前JVM空闲内存)freeMemory(): " + free + "MB<br/>");  
            out.println("因为JVM只有在需要内存时才占用物理内存使用,所以freeMemory()的值一般情况下都很小,<br/>" +  
            "而JVM实际可用内存并不等于freeMemory(),而应该等于 maxMemory()-totalMemory()+freeMemory()。<br/>");  
            out.println("JVM实际可用内存: " + (max - total + free) + "MB<br/>");  
        %>
    


    版权属于: 技术客

    原文地址: https://www.sunjs.com/article/detail/0b56c0908eb54fec8a0ab04031a01bd1.html

    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。




    展开全文
  • JAVA JVM内存模型

    2019-07-22 17:32:05
    内存通过read指令读取数据 数据写入内存 线程执行引擎通过assign指令往工作内存写入。 线程工作内存通过store指令,到主内存。 主内存通过write指令写入数据 数据是怎么做同步 主要是在线程工作内存与主内存这2...

    JMM内存模型

    JMM执行流程:

    在这里插入图片描述

    从内存获取共享数据

    1. 线程执行引擎通过use指令获取工作内存。
    2. 线程工作内存通过load指令,到主内存。
    3. 主内存通过read指令读取数据

    数据写入内存

    1. 线程执行引擎通过assign指令往工作内存写入。
    2. 线程工作内存通过store指令,到主内存。
    3. 主内存通过write指令写入数据

    数据是怎么做同步

    主要是在线程工作内存与主内存这2块之间做同步操作

    展开全文
  • 图片来源于:JVM内存结构 VS Java内存模型 VS Java对象模型JVM在运行时将内存大致划分为以上5个主要的区域:寄存器(又称计数器,Program Counter Register)、虚拟机栈、本地方法栈、堆、方法区。如上图所示,堆和...

    388dab829212b3d9b5d201a2ee2b336f.png

    02280136638a24cd3f721c8a092b9b3d.png

    图片来源于:JVM内存结构 VS Java内存模型 VS Java对象模型

    JVM在运行时将内存大致划分为以上5个主要的区域:寄存器(又称计数器,Program Counter Register)、虚拟机栈、本地方法栈、堆、方法区。

    如上图所示,堆和方法区是所有线程共享的。也就是说该区域内的某个数据可能被不同的线程读取和修改。

    • 程序计数器(Program Counter Register)

    是一小块内存空间,主要代表当前线程所执行的字节码行号指示器。可以通过改变这个值来达到分支、循环、跳转、异常处理、线程恢复等多种基础功能。每个线程拥有自己的计数器,因此可以互不干扰。

    • 虚拟机栈(Java Virtual Machine Stacks)

    主要用来储存方法的执行调用相关信息。每个方法执行时都会创建一个栈桢,方法结束后就会出栈。

    • 本地方法栈(Native Method Stacks)

    这部分主要与虚拟机用到的 Native 方法相关,一般情况下,我们无需关心此区域。

    • Java堆(Java Heap)

    虚拟机启动时创建。线程共享。一般来说占用空间最大。主要用来存放对象实例。此空间被占满时会抛出OOM异常。老生常谈的垃圾回收也和此区域有关。

    • 方法区(Method Area)

    又称Non-Heap(非堆)。主要用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。也会抛出OutOfMemoryError异常。

    在方法区中存在一个叫运行时常量池(Runtime Constant Pool)的区域,它主要用于存放编译器生成的各种字面量和符号引用,这些内容将在类加载后存放到运行时常量池中,以便后续使用。比如String字符串。

    参考链接:

    全面理解Java内存模型(JMM)及volatile关键字

    JVM内存结构 VS Java内存模型 VS Java对象模型

    展开全文
  • 处理器内存模型计算机在执行程序时,每条指令都是在__CPU__中执行的,而执行指令过程中,势必涉及到对主存中数据的读取和写入。由于__CPU__的处理速度相比对内存数据的访问速度快很多,如果任何时候对数据的操作都要...

    Java并发是基于共享内存模型实现的。学习并深入地理解__Java内存模型有助于开发人员了解Java的线程间通信机制原理,从而实现安全且高效的多线程功能。

    处理器内存模型

    计算机在执行程序时,每条指令都是在__CPU__中执行的,而执行指令过程中,势必涉及到对主存中数据的读取和写入。由于__CPU__的处理速度相比对内存数据的访问速度快很多,如果任何时候对数据的操作都要通过和内存的交互来进行,会大大降低指令执行的速度。因此在__CPU__里面就有了高速缓存。

    70177275_202008100955480292YU0FXSYMSV0A4Z1G47.jpg

    然而引入高速缓存带来方便的同时,也带来了缓存一致性的问题。当多个处理器的运算任务都涉及同一块主内存区域时,将可能导致各自缓存数据不一致的问题。解决方法是缓存一致性协议(如Intel 的MESI协议)。

    MESI协议保证了每个缓存中使用的共享变量的副本是一致的。当CPU写数据时,如果发现操作的变量是共享变量,会发出信号通知其他CPU将该变量的缓存行置为无效状态。因此当其他CPU需要读取这个变量时,发现自己缓存中缓存该变量的缓存行是无效的,那么它就会从内存重新读取。

    除了增加高速缓存之外,为了使得处理器内部的运算单元能尽量被充分利用,处理器可能会对输入代码进行乱序执行(Out-Of-Order Execution)优化,处理器会在计算之后将乱序执行的结果重组,保证该结果与顺序执行的结果是一致的,但并不保证程序中各个语句计算的先后顺序与输入代码中的顺序一致,因此,如果存在一个计算任务依赖另外一个计算任务的中间结果,那么其顺序性并不能靠代码的先后顺序来保证。

    Java内存模型

    Java内存模型(Java

    Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能保证效果一致的机制及规范。

    为了方便理解Java内存模型,我们可以抽象地认为,所有变量都存储在主内存中(Main Memory),每个线程都拥有一个私有的工作内存(Working Memory),保存了该线程已访问的变量副本。线程对变量的所有操作都必须在工作内存中进行,而不能直接对主存进行操作。

    70177275_202008100955480370WXZNZONJCWJVU4RLR1.jpg

    假设__线程A__要向__线程B__发消息,__线程A__需要先在自己的工作内存中更新变量,再将变量同步到主内存中,随后__线程B__再去主内存中读取A更新过的变量。因而可以看出,JMM通过控制主内存与每个线程的本地内存之间的交互,提供内存可见性保证。

    内存交互操作

    Java内存模型定义的8个操作指令来进行内存之间的交互,如下:

    lread读取主内存的值,并传输至工作内存。

    lload将read的变量值存放到工作内存。

    luse将工作内存的变量值,传递给执行引擎。

    lassign执行引擎对变量进行赋值。

    lstore工作内存将变量传输到主内存。

    lwrite主内存将工作内存传递过来的变量进行存储。

    llock用作主内存变量,它把一个变量在内存里标识为一个线程独占状态。

    lunlock用作主内存变量,它对被锁定的变量进行解锁。

    工作内存和主内存间的指令操作交互,如下图所示:

    70177275_202008100955480401XH9EZM2ZHC0SN7FPVO.jpg

    指令规则

    lread和 load、store和write必须成对出现

    lassign操作,工作内存变量改变后必须刷回主内存

    l同一时间只能运行一个线程对变量进行lock,当前线程lock可重入,unlock次数必须等于lock的次数,该变量才能解锁。

    l对一个变量lock后,会清空该线程工作内存变量的值,重新执行load或者assign操作初始化工作内存中变量的值。

    lunlock前,必须将变量同步到主内存(store/write操作)。

    重排序

    在没有正确同步的情况下,即使要推断最简单的并发程序的行为也很困难。代码如下:

    public class

    PossibleReordering {

    static int x = 0, y =

    0;

    static int a = 0, b =

    0;

    public static void

    main(String[] args) throws InterruptedException {

    Thread one = new

    Thread(new Runnable() {

    public void run() {

    a = 1;

    x = b;

    }

    });

    Thread other = new

    Thread(new Runnable() {

    public void run() {

    b = 1;

    y = a;

    }

    });

    one.start();

    other.start();

    one.join();other.join();

    System.out.println(“(”

    + x + “,” + y + “)”);

    }

    很容易想象PossibleReordering的输出结果是(1,0)或(0,1)或(1:1)的,__但奇怪的是__还可以输出(0,0)。

    由于每个线程中的各个操作之间不存在数据依赖性,因此这些操作可以乱序执行。下图给出了一种可能由重排序导致的交替执行方式,在这种情况中会输出(0,0)。

    70177275_202008100955480479HMM471RNYTPQZP03G6.jpg

    Java源代码到最终实际执行的指令序列,会分别经历下面3种重排序,如图所示:

    70177275_202008100955480495VS9BARG5V1BSK9VPXO.jpg

    在执行程序时,为了提高性能,编译器和处理器会对指令做重排序。重排序分3种类型:

    l编译器优化重排序。编译器在不改变单线程程序语义(as-if-serial semantics)的前提下,可重新安排语句的执行顺序。

    l指令级并行的重排序。现代处理器采用了指令级并行技术来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。

    l内存系统的重排序。由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是在乱序执行。

    先行发生原则(happens-before)

    为了提高执行性能,JMM允许编译器和处理器对指令进行重排序。但是Java语言保证了操作间具有一定的有序性,概括起来就是先行发生原则(happens-before)。也就是说,如果两个操作的关系无法被happens-before原则推导,则无法保证它们的顺序性,有可能发生重排序。happens-before原则包括:

    l程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作

    l锁定规则:一个unlock操作先行发生于后面对同一个锁的lock操作。

    lvolatile变量规则:对一个volatile变量的写操作先行发生于后面对这个变量的读操作

    l线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作

    l线程终结规则:线程中的所有操作都先行发生于对此线程的终止检测

    l线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生

    l对象终结规则:一个对象的初始化完成先行发生于它的finalize()方法的开始

    l传递规则:如果操作A先行发生于操作B,操作B先行发生于操作C,则有A先行发生于操作C。

    实际上,这些规则是由编译器重排序规则和处理器内存屏障插入策略来实现的。

    内存屏障

    内存屏障是一条CPU指令,用于控制特定条件下的重排序和内存可见性问题。即任何指令都不能与内存屏障指令重排序。

    lLoadLoad屏障:对于这样的语句Load1; LoadLoad; Load2,在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。

    lStoreStore屏障:对于这样的语句Store1; StoreStore; Store2,在Store2及后续写入操作执行前,保证Store1的写入操作对其它处理器可见。

    lLoadStore屏障:对于这样的语句Load1; LoadStore; Store2,在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕。

    lStoreLoad屏障:对于这样的语句Store1; StoreLoad; Load2,在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。

    处理器对重排序的支持

    70177275_202008100955480510FNMU1ZMU0N66RLG7SS.jpg

    从上面可以看到不同的处理器架构对重排序的支持也是不一样(其它处理器架构暂不罗列),所以不同的平台JMM的内存屏障施加也略有不同,具体来说,比如 X86 对Load1Load2不支持重排序,那么你就没有必要施加 LoadLoad屏障。

    volatile的内存语义

    volatile关键字用来保证数据可见性,防止指令重排的效果。包括JUC里AQS Lock的底层实现也是基于volatitle来实现。

    lvolatile写的内存语义:当写一个volatile变量的时候,JMM会把该线程对应的本地内存变量值刷新到主内存。

    lvolatile读的内存语义:当读一个volatile变量的时候,JMM会把线程本次内存置为无效。线程接下来将从主内存中读取共享变量(也就是重新从主内存获取值,更新运行内存中的本地变量)。

    final的内存语义

    final修饰的称作域,对于final域,编译器和处理器要遵守两个重排序规则

    l写规则:在构造函数内对一个final域的写入,与随后把这个被构造的对象的引用赋值给一个引用变量,这两个操作不可重排序。

    JMM禁止编译器把final域的写重排序到构造函数之外,

    编译器会在final域写入的后面插入StoreStore屏障,该规则可以保证在对象引用为任意线程可见之前,对象的final域已经被正确初始化,而普通域无法保障。

    l读规则:初次读一个包含final域的对象的引用,与随后初次读这个final域,这两个操作之间不能重排序。

    在一个线程中,初次读对象引用与初次读该对象包含的final域,JMM禁止处理器重排序这两个操作。编译器会在读final域操作的前面插入一个LoadLoad屏障。

    类库Happens-Before

    由于Happens-Before的排序功能很强,因此有时候可以“借助”现有机制的可见性属性。这需要将Happens-Before的程序顺序规则与其他某个顺序规则(通常是监视器锁规则或者volatile变量规则)结合起来,从而对某个未被锁保护的变量的访问操作进行排序。由类库担保的其他happens-before排序包括:

    l将一个元素放入线程安全容器happens-before于另一个线程从容器中获取元素。

    l执行CountDownLatch中的倒计时happens-before于线程从闭锁(latch)的await中返回。

    l释放一个许可证Semaphorehappens-before于从同一Semaphore里获得一个许可。

    lFuture表现的任务所发生的动作happens-before于另一个线程成功地从Future.get中返回。

    l向Executor提交一个Runnable或Callable happens-before于开始执行任务。

    l一个线程到达CyclicBarrier或Exchanger happens-before于相同关卡(barrier)或Exchange点中的其他线程被释放。如果CyclicBarrier使用一个关卡(barrier)动作,到达关卡happens-before于关卡动作,依照次序,关卡动作happens-before于线程从关卡中释放。

    展开全文
  • JVM内存模型和volatile详解Java内存模型随着计算机的CPU的飞速发展,CPU的运算能力已经远远超出了从主内存(运行内存)中读取的数据的能力,为了解决这个问题,CPU厂商设计出了CPU内置高速缓存区。高速缓存区的加入...
  • 003-Java虚拟机JVM内存模型

    千次阅读 2020-05-14 17:08:12
    Java知识点总结系列目录 类加载器将Class文件读取后,放到运行时数据区,然后执行引擎执行或调用本地接口、本地库。 1、方法区(元空间) 线程共享 JDK1.8后叫元空间Metaspace,存储在本地内存中 JDK1.8前叫永久代...
  • 引言本文希望以另外一种维度的思考方式来...JVM内存模型与上下游JVM内存模型类加载器将Class文件读取后,放到运行时数据区,然后执行引擎执行或调用本地接口、本地库。一、JVM内存模型分类JVM内存模型从线程维度归类...
  • 类加载器将Class文件读取后,放到运行时数据区,然后执行引擎执行或调用本地接口、本地库。 1、方法区(元空间) 线程共享 JDK1.8后叫元空间Metaspace,存储在本地内存中:JDK1.8前叫永久代PermGen,存储在堆上 存储...
  • 概述 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个...Java虚拟机运行时数据区域 在JVM的管理下,Java程序员不需要管理内存的分配和释放,这和在C和C++中是完全不一样的。所以,在JVM的帮助下,...
  • 如何查看Java对象占用JVM内存大小

    千次阅读 2018-01-09 17:17:22
    转换成字节类型 之前遇到要查看缓存大小,找了很多方法都不是很合适,从同事那里得知一个很好、很准确的方法。现分享如下: ...private ListMapString,Object>> paramList=new ... //从数据库读取缓存数
  • JVM内存模型 ##内存模型图 四个概念 class文件 class文件就是我们说的字节码文件,它是由.java、.groovy等文件通过编译器解析产出的文件。class文件才是jvm要使用的文件。 class content class content就是class...
  • JVM内存区域

    2020-07-26 18:42:16
    JVM的学习分两个阶段即...2、JVM内存区域:同理JVM内存区域也就是java程序运行时读取、存放相关数据的区域。 3、JVM内存模型:在特定的操作协议下,对特定的内存或高速缓存进行读写访问的过程抽象。 其实JVM内存区.
  • Java 程序中,我们拥有多种新建对象的方式。除了最为常见的new语句之外,我们还可以通过反射机制、Object.clone方法、反序列化以及Unsafe.allocateInstance 方法来新建对象。其中,Object.clone 方法和反序列化...
  • JVM内存结构主要有三大块:堆内存、方法区和栈Java堆是被所有线程共享,是Java虚拟机所管理的内存中最大的一块 Java堆在虚拟机启动时创建。Java堆唯一的目的是存放对象实例,几乎所有的对象实例和数组都在这里...
  •  2.JVM内存使用案例剖析 一、图解JVM内存的三大核心区 二、VM内存使用案例剖析 从JVM调用的角度分析Java程序对内存空间的使用:  1.当JVM进程启动的时候,会从类加载路径中找到包含main 法的入口类JVM;  2...
  • JVM内存

    2020-06-14 01:17:28
    jvm内存 1.程序计数器 program counter register 每个线程都有一个程序计数器 指向方法区中的下一个将要执行的方法字节码 由执行引擎读取下一条指令 2.本地方法栈 native method stack native method stack中登记...
  • 以下有8个操作指令:1.lock(锁定)作用于主内存的变量中,锁定并让某线程独享2.unlock(解锁)作用于主内存的变量中,解锁变量以让其他线程访问3.read(读取)作用于主内存变量中,以便工作内存下一步的load操作4.load(载入...
  • jvm读取内存

    2011-05-19 00:03:00
    importjava.util.Timer;importjava.util.TimerTask;importjava.util.Calendar;importjava.util.GregorianCalendar;/****&lt;p&gt;Title:GCTimerTask&lt;/p&gt;**@authorzhuangyan*@msn:nac...
  • 可访问个人网站进行阅读最新版本一、Java内存区域1.程序计数器:程序计数器(Program Counter Register)是一块较小的内存空间,可以看作是当前线程所执行字节码的行号指示器,指向下一个将要执行的指令代码,由执行...
  • JVM内存模型

    2019-03-27 21:23:40
    根据Java虚拟机规范:JVM内存主要划分为 程序计数器,虚拟机栈,本地方法栈,Java堆,方法区(永久代) 特别说明下,JVM内存模型和Java内存模型是不一样的 JMM规定了所有的变量都存储在主内存(Main Memory)中。每个...
  • 这一期我们讲一下JVM模型中的程序计数器,我们继续来回顾下JVM模型一、JVM模型概述 java虚拟机(JVM)在java程序运行的过程中,会将它所管理的内存划分为若干个不同的数据区域,这些区域有的随着JVM的启动而创建,...
  • JVM内存主要分为:程序计数器,Java虚拟机栈,本地方法栈,Java堆,方法区。 1.程序计数器 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。 在多...
  • Java 虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。 程序计数器: 较小的内存空间,当前...
  • JVM内存结构

    2020-08-17 22:42:47
    JVM内存区域分配 堆 Java堆是各线程共享的内存区域,在jvm启动时创建,这块区域时jvm中最大的,用于存储应用的对象和数组,也是GC主要的回收区,一个jvm实例只存在一个堆内存,堆内存是可以调节的,类加载器读取类...
  • jvm内存

    2021-02-27 11:57:52
     每个线程都有一个程序计算器,就是一个指针,指向方法区中的方法字节码(下一个将要执行的指令代码),由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不记。   2.本地方法栈 Native Method ...
  • Java内存模式JVM总结

    2017-03-24 21:01:41
    1、java是直接支持多线程的,内存同步,变化变量初始化顺序。   2、volatile声明变量是不稳定的,每次使用它都到主存中进行读取。 3、final修饰变量或方法是只读的。不可改变。提高性能,JVM能缓存、...
  • JVM内存学习笔记

    2019-10-07 04:17:00
     jvm内存共分为五个部分,分别是: 程序计数器 Java虚拟机栈 本地方法栈 堆 方法去 1.程序计数器  1.1 含义  程序计数器是一块较小的内存空间,可以当作是当前线程执行的字节码的行号指示器。即程序...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,000
精华内容 800
关键字:

java读取jvm内存

java 订阅