我对JVM内存管理(至少对于SUN的内存管理)有疑问。
我想知道如何控制JVM将未使用的内存发送回OS(以我的情况为Windows)的事实。
我编写了一个简单的Java程序来说明我的期望。使用-
Dcom.sun.management.jmxremote选项运行它,以便例如也可以使用jconsole监视堆。
使用以下程序:
package fr.brouillard.jvm;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;
public class MemoryFree {
private BufferedReader reader = new BufferedReader(new
InputStreamReader(System.in));
private List<byte[]> usedMemory = new LinkedList<byte[]>();
private int totalMB = 0;
private int gcTimes = 0;
public void allocate(int howManyMB) {
usedMemory.add(new byte[howManyMB * 1024 * 1024]);
totalMB += howManyMB;
System.out.println(howManyMB + "MB allocated, total allocated: " +
totalMB + "MB");
}
public void free() {
usedMemory.clear();
}
public void gc() {
System.gc();
System.out.println("GC " + (++gcTimes) + " times" );
}
public void waitAnswer(String msg) {
System.out.println("Press [enter]" + ((msg==null)?"":msg));
try {
reader.readLine();
} catch (IOException e) {
}
}
public static void main(String[] args) {
MemoryFree mf = new MemoryFree();
mf.waitAnswer(" to allocate memory");
mf.allocate(20);
mf.allocate(10);
mf.allocate(15);
mf.waitAnswer(" to free memory");
mf.free();
mf.waitAnswer(" to GC");
mf.gc();
mf.waitAnswer(" to GC");
mf.gc();
mf.waitAnswer(" to GC");
mf.gc();
mf.waitAnswer(" to GC");
mf.gc();
mf.waitAnswer(" to exit the program");
try {
mf.reader.close();
} catch (IOException e) {}
}
}
一旦第一个GC完成(预期),内部堆就释放了,但是内存仅从第三个GC开始才发回OS。第四次之后,已分配的全部内存将发送回操作系统。
如何设置JVM来控制这种行为?实际上,我的问题是我需要在服务器上运行多个CITRIX客户端会话,但是我希望服务器上正在运行的JVM尽快释放内存(我的应用程序中只有很少的高消耗内存功能)。
如果无法控制此行为,我可以让它这样,然后增加OS虚拟内存,让OS根据需要使用它,而不会出现大性能问题。例如,如果在具有足够虚拟内存的4GB服务器上拥有10个1GB内存的Java进程(堆中只有100MB实际分配的对象)会出现问题。
我想其他人已经面临过这样的问题/问题。
谢谢你的帮助。
要控制从Java
5开始的堆向OS的返回,请使用该-XX:MaxHeapFreeRatio
选项,如调整指南中所述。
如果您认为自己的问题与这一问题有明显的不同,请指出如何。
我们有一个简单的微服务设置,基于Windows服务器上的Spring Boot和Java8。 许多服务的负载很低,因为它们是与各种外部合作伙伴的集成。所以它们很多时候都是空闲的。 问题在于,JVM 仅在触发垃圾回收时才会将内存释放回操作系统。因此,服务可能会开始使用32mb,然后为单个请求提供服务并分配2GB内存。如果该服务上没有其他活动,则不会受到 GC 和服务器上的其他服务的影响。 使用Sys
问题内容: 我有一个应用程序对于某些进程暂时需要一定数量的内存/堆。如果可以选择给JVM一个最大堆大小的合理值,那么JVM将从一个小的堆开始,并按需向OS请求更多的内存。 我的问题是,当我的应用程序不再需要大量内存时,JVM是否会将额外的内存还给操作系统(例如,用于其他进程)。目前,即使不再需要,我的应用程序似乎也可以永久保留该内存。 问题答案: JVM确实将内存返回给操作系统,但是非常不情愿,因
存储器工作原理 应用程序如何在计算机系统上运行的呢?首先,用编程语言编写和编辑应用程序,所编写的程序称为源程序,源程序不能再计算机上直接被运行,需要通过三个阶段的处理:编译程序处理源程序并生成目标代码,链接程序把他们链接为一个可重定位代码,此时该程序处于逻辑地址空间中;下一步装载程序将可执行代码装入物理地址空间,直到此时程序才能运行。 程序编译 源程序经过编译程序的处理生成目标模块(目标代码)。一
问题内容: 当我在Linux上使用顶级终端程序时,看不到免费的结果。 我的期望是: 免费地图和清单。 我可以在顶部看到内存使用情况(Linux函数),或者 变得比过去更小。 睡眠开始了。 程序退出。 但是,只有在程序结束时,内存使用量才会变小。 您能解释一下自由功能的逻辑吗? 下面是我的代码。 谢谢。 问题答案: 内存分配到堆上。 当您在程序中请求一些内存时(使用new()或malloc()等),
在阅读了一些像这样的答案和JEP-346之后,我意识到G1确实会将内存释放回操作系统。 然而,它是否将内存释放回操作系统,即使当前内存使用可能低于初始堆内存(即在此JEP之前,在我的案例中为JDK11)? 假设我有一个Java11 VM,运行和设置为,在RAM上,但是我只消耗大约。G1会释放足够的内存回操作系统吗? 我在任何地方都没有找到任何文档说明G1仅限于在发布时考虑Xms阈值。 我在生产过程
内存管理基础 程序可执行文件的结构 一个程序的可执行文件在内存中的结果,从大的角度可以分为两个部分:只读部分和可读写部分。只读部分包括程序代码(.text)和程序中的常量(.rodata)。可读写部分(也就是变量)大致可以分成下面几个部分: .data: 初始化了的全局变量和静态变量 .bss: 即 Block Started by Symbol, 未初始化的全局变量和静态变量(这个我感觉上课真的