Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:线程退出后未回收堆_Java_Multithreading_Memory Leaks - Fatal编程技术网

Java:线程退出后未回收堆

Java:线程退出后未回收堆,java,multithreading,memory-leaks,Java,Multithreading,Memory Leaks,在我最近的项目中,我面临一个奇怪的内存泄漏问题。我有一个“主”代码,它向“处理程序”代码发送消息。通信时,处理程序代码执行固定任务,将结果写入磁盘,然后退出。固定任务通过调用另一个类中的特定函数来执行 在执行此函数的过程中,堆大小(预期)会增加。但是,代码完成后,结果本身不应占用大量空间。人们期望对处理程序调用的完成会导致较小的内存占用。但是,“top”表示处理程序仍然消耗大量内存(RES) 线程退出不应该确保线程消耗的堆被回收吗?我尝试在函数执行后调用System.gc(),但是,它不会强制进

在我最近的项目中,我面临一个奇怪的内存泄漏问题。我有一个“主”代码,它向“处理程序”代码发送消息。通信时,处理程序代码执行固定任务,将结果写入磁盘,然后退出。固定任务通过调用另一个类中的特定函数来执行

在执行此函数的过程中,堆大小(预期)会增加。但是,代码完成后,结果本身不应占用大量空间。人们期望对处理程序调用的完成会导致较小的内存占用。但是,“top”表示处理程序仍然消耗大量内存(RES)

线程退出不应该确保线程消耗的堆被回收吗?我尝试在函数执行后调用System.gc(),但是,它不会强制进行垃圾收集

线程退出不应该确保线程消耗的堆被回收吗?我尝试在函数执行后调用System.gc(),但是,它不会强制进行垃圾收集

尝试添加一些JVM标志以记录GC活动:

-verbose:gc
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
我想你会看到,事实上,空间正在被重新利用。
top
报告的内存占用包括为Java堆保留的空间,而不管它是否用于分配对象。您无法可靠地使用这些数字来监视GC活动

线程终止不一定会触发垃圾回收。您也不应该期望在垃圾收集时进程的占用空间会缩小。JVM将根据需要增加其托管堆的大小,但它不一定会在第一次机会(或者永远)缩小它。如果您的程序的内存使用率曾经达到这些级别,那么JVM没有理由相信它不会再次发生,因此除非系统内存压力非常大,否则JVM不可能立即将内存释放回操作系统(如果有)

线程退出不应该确保线程消耗的堆被回收吗?我尝试在函数执行后调用System.gc(),但是,它不会强制进行垃圾收集

尝试添加一些JVM标志以记录GC活动:

-verbose:gc
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
我想你会看到,事实上,空间正在被重新利用。
top
报告的内存占用包括为Java堆保留的空间,而不管它是否用于分配对象。您无法可靠地使用这些数字来监视GC活动


线程终止不一定会触发垃圾回收。您也不应该期望在垃圾收集时进程的占用空间会缩小。JVM将根据需要增加其托管堆的大小,但它不一定会在第一次机会(或者永远)缩小它。如果您的程序的内存使用率曾经达到这些级别,那么JVM没有理由相信这种情况不会再次发生,因此除非系统内存压力非常大,否则JVM不太可能立即将内存释放回操作系统(如果有的话)。

热点JVM中的垃圾收集器只将内存返回给操作系统“不情愿”。假设应用程序可能会在回收的空间中创建更多的对象。如果GC要返回内存,它将需要再次请求它,并且搅动将导致额外的系统调用,等等

但是,如果JVM注意到堆不必要地大,它将减小堆的大小,这可能最终导致JVM返回一些内存。调整大小的机制记录在Oracle页面上



还应该注意的是,线程的堆栈不是在Java堆中分配的。相反,它位于非堆内存段中,该内存段通常在线程启动时从操作系统请求,并在线程终止时释放。

热点JVM中的垃圾收集器只是“不情愿地”将内存返回给操作系统“。假设应用程序可能会在回收的空间中创建更多对象。如果GC要返回内存,那么它将需要再次请求它,而搅动将导致额外的系统调用,等等

但是,如果JVM注意到堆不必要地大,它将减小堆的大小,这可能最终导致JVM返回一些内存。此Oracle页面记录了调整大小的机制



还应该注意的是,线程的堆栈不是在Java堆中分配的。相反,它存在于非堆内存段中,该内存段通常在线程启动时从操作系统请求,在线程终止时释放

如果有的话,不情愿地+1。内存可用于JVM的其他部分,但极有可能永远不会将其返回到操作系统中。+1(如果有的话)。内存可用于JVM的其他部分,但很可能永远不会返回操作系统。