我有一个非常简单的Web服务器类(基于Java SE的HttpServer类).
当我使用此命令启动编译的类来限制内存使用时:
java -Xmx5m -Xss5m -Xrs -Xint -Xbatch Test
现在,如果我使用top命令检查内存,则表示执行我的类的Java进程使用~31MB的驻留内存.
我想知道30MB用于什么?
正如评论和答案所暗示的那样,在测量JVM内存使用时还需要考虑许多其他因素.但是,我认为任何答案都没有进入足够深度.
让我们回答"我想知道30MB用于什么?"的问题.脑袋上.为此,这是一个简单的java类:
// HelloWorld.java
public class HelloWorld {
public static void main(String[] args) throws Exception {
System.out.println("Hello world!");
Thread.sleep(10000); // wait 10 seconds so we can get memory usage
}
}
Run Code Online (Sandbox Code Playgroud)
现在使用堆约束编译并运行它:
$ nohup java -Xms2m -Xmx2m HelloWorld & # run in background
$ ps aux | awk 'NR==1; /[H]elloWorld/'
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
chaospie 6204 6.0 0.1 2662860 23040 pts/2 Sl 19:15 0:00 java -Xms2m -Xmx2m HelloWorld
Run Code Online (Sandbox Code Playgroud)
看一下上面的RSS(Resident Set Size,或者这个进程使用了多少内存),我们看到JVM的进程使用了大约23MB的内存.为了了解原因,让我们做一些分析.获得良好概述的最快方法是打开NativeMemorytracking使用jcmd工具的VM.native_memory命令.那么,让我们再次运行我们的应用程序:
$ nohup java -XX:NativeMemoryTracking=summary -Xms2M -Xmx2M HelloWorld &
[2] 6661
nohup: ignoring input and appending output to 'nohup.out'
$ ps aux | awk 'NR==1; /[H]elloWorld/'
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
chaospie 6661 5.0 0.1 2662860 23104 pts/2 Sl 19:21 0:00 java -XX:NativeMemoryTracking=summary -Xms2M -Xmx2M HelloWorld
$ jcmd 6661 VM.native_memory summary
6661:
Native Memory Tracking:
Total: reserved=1360145KB, committed=61177KB
- Java Heap (reserved=2048KB, committed=2048KB)
(mmap: reserved=2048KB, committed=2048KB)
- Class (reserved=1066093KB, committed=14189KB)
(classes #402)
(malloc=9325KB #146)
(mmap: reserved=1056768KB, committed=4864KB)
- Thread (reserved=20646KB, committed=20646KB)
(thread #21)
(stack: reserved=20560KB, committed=20560KB)
(malloc=62KB #110)
(arena=23KB #40)
- Code (reserved=249632KB, committed=2568KB)
(malloc=32KB #299)
(mmap: reserved=249600KB, committed=2536KB)
- GC (reserved=10467KB, committed=10467KB)
(malloc=10383KB #129)
(mmap: reserved=84KB, committed=84KB)
- Compiler (reserved=132KB, committed=132KB)
(malloc=1KB #21)
(arena=131KB #3)
- Internal (reserved=9453KB, committed=9453KB)
(malloc=9421KB #1402)
(mmap: reserved=32KB, committed=32KB)
- Symbol (reserved=1358KB, committed=1358KB)
(malloc=902KB #86)
(arena=456KB #1)
- Native Memory Tracking (reserved=143KB, committed=143KB)
(malloc=86KB #1363)
(tracking overhead=57KB)
- Arena Chunk (reserved=175KB, committed=175KB)
(malloc=175KB)
Run Code Online (Sandbox Code Playgroud)
让我们分解1:
stack本节中使用的反映了Xss线程数的值乘以,可以得到默认-Xss值java -XX:+PrintFlagsFinal -version |grep ThreadStackSize).堆不仅仅是堆!
请注意,每个区域都有一个committed和一个reserved部分.保持简短
reserved是它可以成长的committed东西,也是目前承诺使用的东西.例如,请参阅以下Java Heap部分:Java Heap (reserved=2048KB, committed=2048KB),reserved我们的
-Xmx价值和承诺是我们的-Xms value,在这种情况下它们是相同的.
另请注意总committed大小 - 它不反映RSS(或RES列top)报告的实际使用情况.它们不同的原因是RSS显示已经并且仍然在物理存储器中使用的所有存储器页面的大小,而committed显示了所使用的存储器,包括不在物理存储器3中的存储器.
还有更多内容,但JVM和操作系统内存管理是一个复杂的主题,所以我希望至少在高层次上回答你的问题.
Arena是使用malloc分配的一大块内存.当退出作用域或留下代码区域时,内存将从这些块中大量释放.这些块可以在其他子系统中重用以保存临时存储器,例如,线程前分配.Arena malloc策略确保没有内存泄漏.所以竞技场作为一个整体被跟踪,而不是单个对象.无法跟踪一些初始内存量.
| 归档时间: |
|
| 查看次数: |
1933 次 |
| 最近记录: |