-
2020-07-13 20:54:06
本文是垃圾回收前站,要想进行垃圾回收,先要看清垃圾回收的效果啊,
涉及模块:psutil(外部模块,需要pip安装的)import os import psutil def show_info(start): pid = os.getpid() #模块名比较容易理解:获得当前进程的pid p = psutil.Process(pid) #根据pid找到进程,进而找到占用的内存值 info = p.memory_full_info() memory = info.uss/1024/1024 print(f'{start} 一共占用{memory:.2f}MB') def func(): show_info('initial') a = [i for i in range(100000)] show_info('created') func() show_info('finished')
- 以上内容为垃圾回收的前站,需要找到占用的内存值是多少,进而查看垃圾回收之后的情况
更多相关内容 -
JAVA技巧(Java多线程运行时,减少内存占用量).pdf
2021-10-23 18:41:32JAVA技巧(Java多线程运行时,减少内存占用量).pdf -
到底一个线程占用多少内存
2021-11-09 20:38:52线程占用多少内存 -
Java 线程究竟占用多少内存
2021-02-26 09:19:24(给ImportNew加星标,提高Java技能)编译:ImportNew/唐尤华dzone.com/articles/how-much-memory-does-a-java-thread-take”更新:“JVM 并没有主动按照线程数量分配“threads ’ 1MB”,这个错误来自 NMT 报告。...(给ImportNew加星标,提高Java技能)
编译:ImportNew/唐尤华
dzone.com/articles/how-much-memory-does-a-java-thread-take
”更新:“
JVM 并没有主动按照线程数量分配 “threads ’ 1MB”,这个错误来自 NMT 报告。Java 8 “committed memory”会自动置为 “reserved memory”。参见
”committed memory“大小由堆栈深度决定,感谢 [Thomas Stuefe][1] 的提醒。
---
[1]:https://dzone.com/users/3720329/tstuefe.html
在 Java 应用总内存消耗中,线程使用的内存占很大一部分。根据应用具体特点,比如 CPU 受限或者 IO 受限,可以选择对应技术限制新建的线程数量。对于 IO 受限应用可以创建线程池,由线程处理 IO 操作,比如在阻塞或等待状态从数据库读取数据、发送 HTTP 请求等。如果是计算密集型应用,可以使用像 Netty 这样的 HTTP 服务器,线程数量少、节省内存。接下来通过具体示例展示一个新线程需要消耗多少内存。
线程内存包括栈帧、局部变量、方法参数等,线程大小默认如下(KB):
```shell
$ java -XX:+PrintFlagsFinal -version | grep ThreadStackSize
intx CompilerThreadStackSize = 1024 {pd product} {default}
intx ThreadStackSize = 1024 {pd product} {default}
intx VMThreadStackSize = 1024 {pd product} {default}
```
1. Java 8 线程内存消耗
```shell
$ java -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary /
-XX:+PrintNMTStatistics -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_212-b03)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.212-b03, mixed mode)
Native Memory Tracking:
Total: reserved=6621614KB, committed=545166KB
- Java Heap (reserved=5079040KB, committed=317440KB)
(mmap: reserved=5079040KB, committed=317440KB)
- Class (reserved=1066074KB, committed=13786KB)
(classes #345)
(malloc=9306KB #126)
(mmap: reserved=1056768KB, committed=4480KB)
- Thread (reserved=19553KB, committed=19553KB)
(thread #19)
(stack: reserved=19472KB, committed=19472KB)
(malloc=59KB #105)
(arena=22KB #34)
```
可以看到两种类型的内存:
“Reserved:” 由操作系统承诺的可用内存大小。但尚未分配,JVM 无法访问
”Committed:“ 已被 JVM 分配,可访问
在“Thread”部分可以看到,‘reserved’ 和 ‘committed’ 大小相同,接近于“线程数 ‘ 1MB”。这时因为 JVM 一开始就尽可能地为线程分配内存。
2. Java 11 线程内存消耗
```shell
$ java -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary /
-XX:+PrintNMTStatistics -version
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.2+9)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.2+9, mixed mode)
Native Memory Tracking:
Total: reserved=6643041KB, committed=397465KB
- Java Heap (reserved=5079040KB, committed=317440KB)
(mmap: reserved=5079040KB, committed=317440KB)
- Class (reserved=1056864KB, committed=4576KB)
(classes #426)
( instance classes #364, array classes #62)
(malloc=96KB #455)
(mmap: reserved=1056768KB, committed=4480KB)
( Metadata: )
( reserved=8192KB, committed=4096KB)
( used=2849KB)
( free=1247KB)
( waste=0KB =0,00%)
( Class space:)
( reserved=1048576KB, committed=384KB)
( used=270KB)
( free=114KB)
( waste=0KB =0,00%)
- Thread (reserved=15461KB, committed=613KB)
(thread #15)
(stack: reserved=15392KB, committed=544KB)
(malloc=52KB #84)
(arena=18KB #28)
```
从上面地结果可以注意到,Java 11 节省了很多内存,不会在线程创建时主动分配 ‘Reserved Memory’。当然,这只是 ’java -version‘ 命令的执行结果。如果试着使用 Java 11,会发现内存分配有显著改进。
感谢阅读,欢迎在下面评论。
看完本文有收获?请转发分享给更多人
关注「ImportNew」,提升Java技能
好文章,我在看❤️
-
Java 的线程到底占用了多少内存?
2021-02-04 12:44:54若是有人问你正在运行的Java 程序的堆占用了多少内存, 你一个命令就给出了答案; 若是有人问你正在运行的 Java 程序的线程栈使用了多少内存, 该怎么得到答案呢? 故事背景 有人的 Java 程序遇到了 OOM,程序崩溃...原文排版比较好. 原文链接: https://mp.weixin.qq.com/s/wA3pUemz5oWJX6Zp9HFIGA
若是有人问你正在运行的 Java 程序的堆占用了多少内存, 你一个命令就给出了答案; 若是有人问你正在运行的 Java 程序的线程栈使用了多少内存, 该怎么得到答案呢?
故事背景
有人的 Java 程序遇到了 OOM, 程序崩溃之前, 只给出了这么一句关键遗言: "java.lang.OutOfMemoryError: unable to create new native thread". 从这一句关键的遗言中, 我们并不能完全推导出它崩溃之前到底发生了什么事情. Google 给出的答案里, 有的说是遇到的操作系统的 limits 限制, 有的说内存真的被用光了.
本文并不想去探讨这个 OOM 的具体原因, 而是去追问其中的一个分支问题: Java 的线程到底占用了多少物理内存?
有关 Xss 和 ThreadStackSize
首先, 根据用途, Java 的内存使用可以分为: 堆区 (年轻代, 老年代, 元数据区) , 栈区, 编译后的代码区, 编译器代码区, GC 管理程序区, JVM 自身的代码区 和 符号区等. 一般情况下, 占大头的是堆区. 栈区根据线程数可能大小不一.
在 JVM 的 flags 里面, 有2个参数是与栈大小相关的. 分别是 -Xss 和 -XX:ThreadStackSize. 我们可以认为2个 flags 其实代表一个意思, 只是一个是简写, 一个是全量写法. 根据官方文档, 它设置的是一个线程 Stack 的大小. 若是不设置, 根据操作系统的不同, 有不同的默认值. 如 64位的 Linux 下, 默认是1MB.
线程栈的大小
是不是根据Xss 的值乘以线程数, 就得到了所有线程栈占用的物理内存大小呢? 于是, 我找到一个基于 JDK 8, 正在运行, 并且线程数目巨大(其实是有线程泄漏的 bug)的程序. 使用 NMT 得到了下面的结果:
这代表什么呢? 当时的活跃线程数大概是13991 个, 栈所声明要使用的内存数14454495KB, 实际提交 (committed) 的 内存约 13.71G. 这是一个声明了使用8核16G 内存的 container 进程, 而这个 Java 进程的栈却告诉我们: 栈使用了13.71G 内存, 加上堆占用的8个多G, 该进程已经提交了24G 多的内存占用 (没开 SWAP). 这明显已经矛盾.
同时, 我们通过 ps 命令可以看到, 该进程占用大约13G 的 RSS 内存. Container 设置的内存最大值是16G, 当前还有500M 的空余. (该 Container 是一个 fat Container, 里面还有其它辅助进程). 这是一个合理的情形.
数据对不上, 至少有一个人在说谎.
NMT 的 bug
NMT 作为 JVM 提供的一个追踪原生内存使用量的工具, 最早主要用来追查内存泄漏的. 主要的内存泄漏大都集中在堆区. 对于栈区, 早期的 NMT 的计算方式主要以线程数乘以每个线程可以使用的最大内存量( Xss)得到的. 所以, 直到2018年, 有人报了这个问题, 才有了这个修复: https://bugs.openjdk.java.net/browse/JDK-8191369.
但是这个修复主要修了 Linux 和 Windows 版本. 所以即便我在 MAC 上下载了 JDK 15的 release 版本, 依旧有这个数据问题.
修复后的结果
我找了一个 Linux 上基于 JDK 11 的程序, 使用 NMT 之后, 终于看到了想要的结果:
这里大约有310个运行中线程, 使用了大概38M, 平均使用100K 多一些. 这才是真正的结果.
为什么保留1M, 却只使用了100K?
这其实就是虚拟内存和真实物理内存差异的原因. 若 Xss 要求是1M, 那么每个线程会申请1M的虚拟内存, 可是大部分线程并不会使用这么多, 也就没必要占用这么多物理内存, 使用多少个页(匿名 page), 就提交多少个页. 若按照每页4K 计算, 也就是平均25个页左右, 就满足了大部分线程的内存需求.
另外, 如果我们查看 IBM JDK 或 Eclipse OpenJ9的文档, 我们可能看到另外2个启动的 flags, 分别是: -Xiss 和 -Xssi. 分别代表栈的 Initial Stack Size (初始值) 和 Stack Size Increment (渐增值). 所以我们之前讨论的 Xss 代表最大值.
-
【java】java 一个线程占用多少内存
2021-07-05 19:21:37偶然看到一个信息,说java的线程默认占用1M内存。然后我就查了查 线程堆栈也会申请内存。堆栈大小由 -Xss 选项指定,默认每个线程1M,幸运的是情况并非那么糟糕。操作系统会以延迟分配的方式分配内存页面,比如在第... -
Java 进程占用内存过多,幕后元凶原来是线程太多
2021-02-12 16:23:03一个线程默认占用空间大小 1M,10万多个线程那就是 10个多G,加上堆内存占用和机器上其他服务的内存占用,内存飙到 15G 就对的上了。 谁的问题谁处理 有问题就找问题就这么难吗,不承认自己的程序有问题是怎么想的... -
一个jvm线程占用多少操作系统内存
2021-02-26 11:14:30发现内存计算对不上由于我们这边设置的Xss是512K,即一个线程栈大小是512K,而由于线程共享其它MM单元(线程本地内存是是现在线程栈上的),所以实际线程堆外内存占用数量也是512K。进行如下计算:... -
多线程会占用大量的内存?NO,每个线程只会用几百KB内存。
2020-09-23 20:46:50文章目录1 问题描述2 测试原理3 测试数据4 测试结论...在Windows操作系统下,启动10万个线程,比较前后内存的占用量,以计算出每个线程的内存占用情况。 这里有几点注意: 本测试结果不应该受语言影响,因为线程的调度 -
分析java 线程占用内存_Java线程:保留的内存分析
2020-06-06 07:25:52分析java 线程占用内存 ... 我们还将尝试证明过多的垃圾回收或Java堆空间的内存占用问题通常不是由真正的内存泄漏引起的,而是由线程执行模式和大量的短期对象引起的。 背景 正如您从我过去的JVM概... -
C# 获取当前所有进程线程CUP占用率
2016-09-14 18:42:57监控系统所有进程的CPU使用情况 显示CPU占用大于0的进程,定时刷新 可以查看当前系统运行的各进程cpu占用率 在CSDN上找到两个都不太好用,自己写了一个VS...用途:查看自己写的程序那个线程运行时间最多,耗资源等。 -
02-----linux下多线程程序占用虚拟内存非常高
2021-05-25 19:53:21所以开撸,发现当我在调试一个线程池时,发现使用了一两个小时后,虚拟内存占用得非常高。然后我开始分析,一开始我先写了一个不带调整线程的线程池,发现线程池开启几个小时后,虚拟内存都是很稳定,基本也就正常的... -
Linux 多线程内存占用分析
2014-08-11 22:39:11大概现象为,一个很简单的程序逻辑,开启了几个线程,程序本身并没有过多的申请内存,或者说根本没有申请内存,但是在实际运行起来后,通过PS命令和status 查看内存占用居然达到了40M,详细分析了smaps文件没有得到... -
linux查看进程内存使用情况,以及将线程情况输出文件
2021-05-12 12:41:39用jmap把进程内存使用情况dump到文件中,再用jhat分析查看。jmap进行dump命令格式如下:jmap-dump:format=b,file=/tmp/dump.dat21711 -------->进程idjhat-port 10099 /tmp/dump.dat运行在10099端口然后浏览器加... -
Linux下创建一个线程占用多少内存
2018-09-08 12:57:34在前面的博客进程分配资源中,我们了解到,在32位平台下,系统会给一个进程分配4G的虚拟内存供进程使用。 因此,我们知道,一个进程被创建时将被分配有4G的虚拟内存。事实上,并不是每次都会用完这4G内存的,下面的... -
java线程池常驻线程占内存吗
2021-02-26 08:35:38看了下代码: public void run() { try { Runnable task = firstTask;... 另外,线程常驻内存当然是占用内存的,但是线程资源占用的量是很小的,但是我们用来实现逻辑的其他资源占用内存的量就不好说啦。 -
linux查看进程下的线程及其cpu和内存利用率
2022-01-05 15:41:16首先我们需要知道进程的PID,输入命令:netstat -tnlp -all,在最后一... 用进程PID查看线程的cpu和内存利用率,输入命令:top -H -p 进程PID,第一列是线程的PID,%CPU和%MEM就是cpu和内存利用率,这个是实时更新的。 -
如何找到占用CPU和内存最高的线程
2017-03-01 16:10:26title: 如何找到占用CPU和内存最高的线程date: 2017-03-01tags: java一、如何找到CPU和内存占用最高的线程 代码示例我们先来写一段代码 @Test public void testLinuxTop() throws Exception{ boolean b=true; ... -
线程占用内存多大?
2016-06-03 17:49:37#include #include int main() { // char *p =(char *) malloc(1024*1024); while(1) { sleep(1); } return 0; }主线程main占用内存大小为4188K ,大约4M 示例2: # -
CPU,进程, 线程的占用关系
2020-09-15 22:35:21进程是cpu,内存等资源占用的基本单位,线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位,线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一... -
可以查看多线程cpu占用率的工具
2010-04-21 18:08:57用在嵌入式linux平台上,通常busybox的top无法看到多线程应用的每个线程的cpu占用率,特地编写了这个小工具. -
Linux查看进程的内存占用情况
2021-02-28 15:15:06能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器内容解释:PID:进程的IDUSER:进程所有者PR:进程的优先级别,越小越优先被执行NInice:值VIRT:进程占用的虚拟内存RES:进程占用的物理内存... -
C#中线程占用内存过大解决方法
2017-07-10 10:03:03C#中线程占用内存过大...项目中用到了多线程,而且是1000线程并发运行,发现内存占用过高,于是对项目里用到的对象逐个测试,发现是线程对象占用内存 Thread[] threads = new Thread[1000]; for(int i = 0; i) { -
关于 Java 应用的 线程栈内存大小
2021-03-05 13:08:07关于 Java 应用的 线程栈内存大小作者: 认真生活每一天 更新时间:2021-01-29 08:13:00 原文链接右侧开启环境实践本页内容对于 Java 应用, 对于内存的占用, 主要是Java堆, 通常我们为了性能考虑, 会对堆设置最大值,... -
springboot内存占用过高问题排查 - jvm内存使用分析
2020-10-27 22:04:47排查springboot内存占用过高问题 所需命令: ps命令:Linux命令。强大的进程状态监控命令。可以查看进程以及进程中线程的当前CPU使用情况。属于当前状态的采样数据。 top命令:Linux命令。可以查看实时的CPU使用情况... -
java多线程-cpu内存占用-定位分析
2016-03-08 13:16:23一,创建测试环境(windows) 二,定位 正文: 测试环境如下: 建立2个线程类,一个run死循环执行大量io,另一个run死循环执行1...可看出,java进程里2个线程高占用cpu。 现在大概定位问题了,如果对程序很熟悉 -
.NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用?
2019-08-30 14:55:47都知道可以在任务管理器中查看进程的 CPU 和内存占用,那么如何通过 .NET 编写代码的方式来获取到 CPU 和内存占用呢? .NET 中提供了 PerformanceCounter 类型,可以用来监视系统中大量的性能问题。 本文内容获取... -
JVM内存区域,开线程影响哪块内存
2019-07-19 22:57:49就为其分配一个Program Counter Register(程序计数器), VM Stack(虚拟机栈)和Native Method Stack (本地方法栈),当线程终止时,三者(虚拟机栈,本地方法栈和程序计数器)所占用的内存空间也会被释放掉。...