当前位置: 首页 > 面试题库 >

JVM将内存发送回操作系统

米飞龙
2023-03-14
问题内容

我对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, 未初始化的全局变量和静态变量(这个我感觉上课真的