java 物理内存_聊聊Java中的内存

JVM的内存

先放一张JVM的内存划分图,总体上可以分为堆和非堆(粗略划分,基于java8)

a4ecb6aac4d89948d2db01c7b03957f5.png

那么一个Java进程最大占用的物理内存为:

Max Memory = eden + survivor + old + String Constant Pool + Code cache + compressed class space + Metaspace + Thread stack(*thread num) + Direct + Mapped + JVM + Native Memory

堆和非堆内存

堆和非堆内存有以下几个概念:

init

表示JVM在启动时从操作系统申请内存管理的初始内存大小(以字节为单位)。JVM可能从操作系统请求额外的内存,也可以随着时间的推移向操作系统释放内存(经实际测试,这个内存并没有过主动释放)。这个init的值可能不会定义。

used

表示当前使用的内存量(以字节为单位)

committed

表示保证可供 Jvm使用的内存大小(以字节为单位)。 已提交内存的大小可能随时间而变化(增加或减少)。 JVM也可能向系统释放内存,导致已提交的内存可能小于 init,但是committed永远会大于等于used。

max

表示可用于内存管理的最大内存(以字节为单位)。

NMT追踪内存

NMT(Native Memory tracking)是一种Java HotSpot VM功能,可跟踪Java HotSpot VM的内部内存使用情况(jdk8+)。

本文简单介绍下该工具的使用,主要用来解释Java中的内存

开启

在启动参数中添加-XX:NativeMemoryTracking=detail

查看

jcmd 进程id VM.native_memory summary scale=MB

输出结果

Native Memory Tracking:

Total: reserved=6988749KB, committed=3692013KB

堆内存

- Java Heap (reserved=5242880KB, committed=3205008KB)

(mmap: reserved=5242880KB, committed=3205008KB)

类加载信息

- Class (reserved=1114618KB, committed=74642KB)

(classes #10657)

(malloc=4602KB #32974)

(mmap: reserved=1110016KB, committed=70040KB)

线程栈

- Thread (reserved=255213KB, committed=255213KB)

(thread #248)

(stack: reserved=253916KB, committed=253916KB)

(malloc=816KB #1242)

(arena=481KB #494)

代码缓存

- Code (reserved=257475KB, committed=46551KB)

(malloc=7875KB #10417)

(mmap: reserved=249600KB, committed=38676KB)

垃圾回收

- GC (reserved=31524KB, committed=23560KB)

(malloc=17180KB #2113)

(mmap: reserved=14344KB, committed=6380KB)

编译器

- Compiler (reserved=598KB, committed=598KB)

(malloc=467KB #1305)

(arena=131KB #3)

内部

- Internal (reserved=6142KB, committed=6142KB)

(malloc=6110KB #23691)

(mmap: reserved=32KB, committed=32KB)

符号

- Symbol (reserved=11269KB, committed=11269KB)

(malloc=8544KB #89873)

(arena=2725KB #1)

nmt

- Native Memory Tracking (reserved=2781KB, committed=2781KB)

(malloc=199KB #3036)

(tracking overhead=2582KB)

- Arena Chunk (reserved=194KB, committed=194KB)

(malloc=194KB)

- Unknown (reserved=66056KB, committed=66056KB)

(mmap: reserved=66056KB, committed=66056KB)

nmt返回结果中有reserved和committed两个值,这里解释一下:

reserved

reserved memory 是指JVM 通过mmaped PROT_NONE 申请的虚拟地址空间,在页表中已经存在了记录(entries),说白了,就是已分配的大小

在堆内存下,就是xmx值,jvm申请的最大保留内存。

committed

committed memory 是JVM向操做系统实际分配的内存(malloc/mmap),mmaped PROT_READ | PROT_WRITE,相当于程序实际申请的可用内存。

在堆内存下,当xms没有扩容时就是xms值,最小堆内存,扩容后就是扩容后的值,heap committed memory,。

注意,committed申请的内存并不是说直接占用了物理内存,由于操作系统的内存管理是惰性的,对于已申请的内存虽然会分配地址空间,但并不会直接占用物理内存,真正使用的时候才会映射到实际的物理内存。所以committed > res也是很可能的

Linux内存与JVM内存

再来说说JVM内存与该进程的内存。

现在有一个Java进程,JVM所有已使用内存区域加起来才2G(不包括Native Memory,也没有显式调用JNI的地方),但从top/pmap上看该进程res已经2.9G了

#heap + noheap

Memory used total max usage

heap 1921M 2822M 4812M 39.93%

par_eden_space 1879M 2457M 2457M 76.47%

par_survivor_space 4M 307M 307M 1.56%

cms_old_gen 37M 57M 2048M 1.84%

nonheap 103M 121M -1 85.00%

code_cache 31M 37M 240M 13.18%

metaspace 63M 74M -1 85.51%

compressed_class_space 7M 9M 1024M 0.75%

direct 997K 997K - 100.00

mapped 0K 0K - NaN%

#top

top -p 6267

top - 17:39:40 up 140 days, 5:39, 5 users, load average: 0.00, 0.01, 0.00

Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie

Cpu(s): 0.2%us, 0.1%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st

Mem: 8059152k total, 5255384k used, 2803768k free, 148872k buffers

Swap: 0k total, 0k used, 0k free, 1151812k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

6267 root 20 0 8930m 2.9g 17m S 0.0 37.6 4:13.31 java

那么其余的0.9G内存去哪了呢?

这时候就要介绍下JVM与Linux内存的联系了

当Java程序启动后,会根据Xmx为堆预申请一块保留内存,并不会直接使用,也不会占用物理内存

然后申请(malloc之类的方法)Xms大小的虚拟内存,但是由于操作系统的内存管理是惰性的,有一个内存延迟分配的概念。malloc虽然会分配内存地址空间,但是并没有映射到实际的物理内存,只有当对该地址空间赋值时,才会真正的占用物理内存,才会影响RES的大小。

所以可能会出现进程所用内存大于当前堆+非堆的情况。

比如说该Java程序在5分钟前,有一定活动,占用了2.6G堆内存(无论堆中的什么代),经过GC之后,虽然堆内存已经被回收了,堆占用很低,但GC的回收只是针对Jvm申请的这块内存区域,并不会调用操作系统释放内存。所以该进程的内存并不会释放,这时就会出现进程内存远远大于堆+非堆的情况。

至于Oracle文档上说的,Jvm可能会向操作系统释放内存,经过测试没有发现释放的情况。不过就算有主动释放的情况,也不太需要我们程序关心了。

RES(Resident Set Size)是常驻内存的意思,进程实际使用的物理内存

参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/283106.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.Net CoreRabbitMQ基本使用

队列模式https://www.rabbitmq.com/getstarted.html对以上几种模式进行简要分类,可以分成如下三类(RPC暂不考虑)简单队列模式,单发单收,一对一模式Worker模式,单发多收(一个消息一个接收者,多个消息多个接收者)&#x…

【微信小程序】:实现轮播图3秒滚动

wxml模板&#xff1a;&#xff08;数据一维数组&#xff09; <scroll-view scroll-y"true"><swiper autoplay"auto" interval"3000" duration"500"><block wx:for"{{home_pics}}" wx:for-index"index…

Linux包系列的知识(附:Ubuntu16.04升级到18.04的案例)

Linux基础&#xff1a;https://www.cnblogs.com/dunitian/p/4822808.html#linux 之前看到朋友还动不动 apt-get update upgrade&#xff0c;就很纳闷&#xff0c;后来发现原来他只是知道这个更新命令却不知其意&#xff0c;所以每次安装个包就把所有apt-get的常用清除更新命令打…

java获取tomcat目录结构_Tomcat目录结构详解

Tomcat目录结构图如下&#xff1a;bin目录存放一些可执行的二进制文件&#xff0c;.sh结尾的为linux下执行命令&#xff0c;.bat结尾的为windows下执行命令。catalina.sh&#xff1a;真正启动tomcat文件&#xff0c;可以在里面设置jvm参数。startup.sh&#xff1a;启动tomcat(需…

智慧农业物联网云平台方案

2019独角兽企业重金招聘Python工程师标准>>> 多比智慧农业物联网云平台解决方案结合了最先进的物联网、云计算、传感器、自动控制等, 在浏览器或手机客户端实时显示大棚、大田、温室等温度、湿度、PH值、光强度、CO2&#xff0c;或作为自动控制的参变量参与到自动控…

Linux下汇编语言学习笔记65 ---

这是17年暑假学习Linux汇编语言的笔记记录&#xff0c;参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译《汇编语言基于Linux环境》的书&#xff0c;喜欢看原版书的同学可以看《Assembly Language Step-By-Setp:Programming with Linux 3rd Edition》&#xff0c;非常感谢该…

python:继承日志模块生成自定义日志

1 继承日志模块生成自定义日志 from __future__ import absolute_importimport os import sys import time import datetime import logging import logging.handlers import tempfileDATE_FORMAT %Y-%m-%d %H:%M:%Sdef create_logfile():if SYAPI_LOG_TEST in os.environ:val…

使用JDBC获取Oracle连接时报错

The Network Adapter could not establish the connection 网络适配器不能创建连接 作为初学者的来说&#xff0c;这个问题让我找了好多次&#xff0c;每次重新开启电脑时就可以正常获取连接&#xff0c;过了一会儿&#xff0c;自己不知道做了什么就会又报错&#xff0c;…

.Net CoreRabbitMQ消息转发可靠机制(上)

前言生产者发送消息到了队列&#xff0c;队列推送数据给了消费者&#xff0c;这里存在一些问题需要思考下生产者如何确保消息一定投递到了队列中RabbitMQ 丢失了消息(下文暂不涉及这块)队列如何确保消费者收到了消息呢生产者可靠发送执行流程当生产者将消息发送出去后&#xff…

堆栈的理解

Java把内存分成两种&#xff0c;一种叫做栈内存&#xff0c;一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时&#xff0c;java就在栈中为这个变量分配内存空间&#xff0c;当超过变量的作用域后&am…

MySQL安装时出现的问题

mysql正常安装结束之后需要连接你所安装的数据库的时候出现下面的错误: Client does not support authentication protocol requested by server;consider upgrading mysql client 解决方法:启动:mysql 8.0 command line client 之后输入下面的代码即可。use mysql;ALTER USER…

一个java文件中可包含多个main方法

java中的main方法是java应用程序的入口&#xff0c;java程序在运行时&#xff0c;首先调用执行main方法。但并不是说java中只能有一个main方法&#xff0c;不同类中都可以包含main方法。当JVM进行编译时&#xff0c;会提示选择其中一个main方法作为编译的入口。 转载于:https:/…

linux java性能监控工具_Linux实时监控工具Nmon使用

官网&#xff1a;http://nmon.sourceforge.net/pmwiki.php?nMain.H网络解压&#xff1a;#chmod ux nmon_x86_64_sles11#chmod 777 nmon_x86_64_sles11版本不同&#xff0c;对应文件也不同启动&#xff1a;# ./nmon_x86_64_sles11按C显示CPU信息&#xff0c;再按一次C关闭按M显…

【SRM-05 B】无题?

Description 有一个拥有n个城市的国家。这个国家由n-1条边连接起来。有一天国家发生叛乱。叛军已占领了一些城市。如果叛军占领的城市中&#xff0c;存在两个城市之间有边直接相连&#xff0c;则称这种情况是坏的。现在并不知道叛军占领了那些城市&#xff0c;问有多少种情况是…

MapReduce 2 中一些基础数据类型

1. LongWritable, IntWritable, Text 均是 Hadoop 中实现的用于封装 Java 数据类型的类&#xff0c;这些类实现了WritableComparable接口&#xff0c;都能够被串行化从而便于在分布式环境中进行数据交换&#xff0c;以及进行大小比较。你可以将它们分别视为long,int,String 的替…

分享一些 Java 后端的个人干货

学习 Java 也有了不少时间&#xff0c;入 Java 后台的坑也有了一段时日。这段时间里&#xff0c;听过许多前辈的经验与分享&#xff0c;也看过许多大佬的文章和作品。找了个时间整理和总结了一下我个人到目前为止一路以来的听到看到或者自己感悟到的干货。 这篇文章可能更多的是…

.NET MAUI实战 Routing

1.详情本章继续分享.NET MAUI中的路由&#xff0c;这个概念依旧是在Prism里存在过的概念。如果使用过Prism框架的小伙伴使用该机制上手速度是非常快的。接下来一起来看看什么是路由。.NET 多平台应用 UI (.NET MAUI) Shell 包含基于 URI 的导航体验&#xff0c;该体验使用路由导…

分享Web应用运行的细节问题:预编译提高网站性能、跟踪用户习惯和解决线程同步...

在这个文章里&#xff0c;我将分享一下在iOpenWorks.com这个网站试运行中碰到的若干问题和解决方案&#xff0c;这些问题包含了&#xff1a;&#xff08;1&#xff09;如何通过ASP.NET MVC预编译提高性能&#xff1b;&#xff08;2&#xff09;如何知道网站在运行中&#xff0c…

mondrain配置mysql_mondrian 4.7 源码部署(示例代码)

mondrian是一个开源的数据分析工程, 网上有关mondrian3.X的源码部署比较多, 有关4.X的部署较少. 目前官方推荐使用的时mondrian3.7的修订版, 可以再github上下载到最近更新维护的mondrian-master, 下载下来后基本上只需要按部就班的使用maven build一下就可以正常使用了, 如有问…

腾讯云DevOps技术揭秘:新时代运维重器Tencent Hub最佳实践

随着云计算和容器技术的发展以及微服务架构的兴起&#xff0c;服务能够实现细粒度的部署&#xff0c;维护和伸缩。在使开发人员能快速开发的同时&#xff0c;这些技术也给系统和应用的运维带来了更大的挑战。DevOps理念也应运而生&#xff0c;强调研发和运维的流程及工具的自动…