标签: java-memory-leaks

为什么 Java11 将 java.util.zip.ZipFile$Source 保留在堆上?

有人可以帮助我理解我所看到的是 Java11 中故意的、正确的行为还是某种泄漏吗?让我们看一个愚蠢简单的 hello world 应用程序:

package com.example;

public class HelloWorld {
    public static void main(String[] args) throws InterruptedException {
        for( int i =0 ; i < 50; i++){
            Thread.sleep(1000);
            System.out.println("hello " + i);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

唯一有趣的部分是 jar 依赖项。它可以是任何 jar,但为了让问题更加引人注目,让我们使用一个大的 - 旧的 gwt-user jar,它重 30MB:

plugins {
    id 'java'
}

group 'com.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    // https://mvnrepository.com/artifact/com.google.gwt/gwt-user
    compile group: 'com.google.gwt', name: 'gwt-user', version: '2.7.0'
}

Run Code Online (Sandbox Code Playgroud)

运行应用程序,打开 jvisualvm,进行转储并查找保留的一组java.util.zip.ZipFile$Source

jvisualvm 堆转储

类路径中的 jar(实际上从未使用过)占用 1.5MB 的堆。它不会在 GC …

memory-leaks heap-dump java-memory-leaks java-11 openjdk-11

8
推荐指数
1
解决办法
5975
查看次数

在导致内存碎片问题的次要 gc 之后,Java 对象不必要地升级到老年代

我们的应用程序面临一个奇怪的内存泄漏问题。

GC 配置:ParNew + CMS

某种类型的对象过早地被提升到老年代并导致严重的碎片问题。

  1. 幸存者有足够的空间来容纳这些物品
  2. 老化阈值是 15 个周期,并且没有在此基础上发生过早提升。

关于这些对象:这些是使用 Java 辅助库创建的代理对象。

由于这些对象的不必要的提升,老年代被污染的太快,严重的碎片正在发生。

我们的观察:

  1. 对象仅在 eden 中分配。没有大小相关的问题。
  2. 对象的范围非常小,有资格在下一次次要 gc 中进行 GC。
  3. 为了确保这一点,我们在finalize() 中打印了一些记录器,并观察到范围在请求后立即结束。就在第一次次要 GC 之后。

注意:finalize() 只是为了跟踪目的而添加的。即使没有 finalize() 老一代促销也会发生。

  1. 在一次次要 gc 之后:
  • 期望对象将被清除。
  • 但是对象被提升到老年代。在多个堆转储的帮助下,我们能够跟踪对象升级到老年代。
  1. 所有这些对象都在 old gen 中累积,并由 old gen GC 进行 GC。
  2. 此行为仅在生产服务器中可见,在测试环境中不可重现。

请建议如何进一步进行并解决此问题。

另一个有趣的更新:使用 G1GC,当使用 G1GC 时,对象会被正确清除。使用 finalize() 方法检查,在第一个循环之后,对象变得无法访问。在下一个小循环之后,对象不在那里。对于 G1GC,问题不存在。

java garbage-collection memory-leaks java-memory-leaks java-assist

5
推荐指数
0
解决办法
117
查看次数

LeakCanary 没有提供足够的信息来识别泄漏

我正在使用 LeakCanary,但堆分析结果没有提供足够的信息来检测任何泄漏。它只提到活动正在泄漏。

\n
D/LeakCanary: \xe2\x80\x8b\n    ====================================\n    HEAP ANALYSIS RESULT\n    ====================================\n    1 APPLICATION LEAKS\n    \n    References underlined with "~~~" are likely causes.\n    Learn more at https://squ.re/leaks.\n    \n    298153 bytes retained by leaking objects\n    Signature: a610bac3ef989ac5dc5a69244fc2882de5617\n    \xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n    \xe2\x94\x82 GC Root: System class\n    \xe2\x94\x82\n    \xe2\x94\x9c\xe2\x94\x80 android.provider.FontsContract class\n    \xe2\x94\x82    Leaking: NO (MyApplication\xe2\x86\x93 is not leaking and a class is never leaking)\n    \xe2\x94\x82    \xe2\x86\x93 static FontsContract.sContext\n    \xe2\x94\x9c\xe2\x94\x80 com.example.MyApplication instance\n    \xe2\x94\x82    Leaking: NO (Application is a singleton)\n    \xe2\x94\x82    mBoundService instance of com.example.services.SessionService\n    \xe2\x94\x82    mBase instance of …
Run Code Online (Sandbox Code Playgroud)

android memory-leaks memory-profiling android-activity java-memory-leaks

3
推荐指数
1
解决办法
1812
查看次数

使用jersey的JAX RS的内存问题

我们目前在高效的服务器上遇到了一些问题,因为它消耗的内存过多.其中一个漏洞可能来自球衣客户端.我发现了以下两个问题以及如何:

  1. 如何正确共享JAX-RS 2.0客户端
  2. 关闭JAX RS客户端/响应
  3. https://blogs.oracle.com/japod/entry/how_to_use_jersey_client

我从中获得了什么,我应该重用客户端,还可能重用WebTargets?同时建议关闭响应,但是如何使用.request()执行此操作?

代码示例,使用不同的路径每小时调用大约1000次:

public byte[] getDocument(String path) {
    Client client = ClientBuilder.newClient();
    WebTarget target = client.target(config.getPublishHost() + path);
    try {
        byte[] bytes = target.request().get(byte[].class);
        LOGGER.debug("Document size in bytes: " + bytes.length);
        return bytes;
    } catch (ProcessingException e) {
        LOGGER.error(Constants.PROCESSING_ERROR, e);
        throw new FailureException(Constants.PROCESSING_ERROR, e);
    } catch (WebApplicationException e) {
        LOGGER.error(Constants.RESPONSE_ERROR, e);
        throw new FailureException(Constants.RESPONSE_ERROR, e);
    } finally {
        client.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是如何正确使用API​​来防止上述示例的泄漏?

java rest performance jersey java-memory-leaks

2
推荐指数
1
解决办法
2316
查看次数

TreeMap&lt;Long, Long&gt; 集合粒度需要多少内存?

TreeMap<Long, Long>充满 1000 个(全部唯一)键值对的集合需要多少内存?

是的,我可以只观察内存转储,但需要详细了解原因:

  • Long= n 字节
  • Entry<Long, Long > = 2n 字节,因此 1000 个条目 = 2000n 字节
  • 树节点中的引用:k 字节,1 个节点有 2 个指向子节点的链接,因此 2k 字节,
  • ETC。

总计: X ?

java treemap java-memory-leaks java-heap

2
推荐指数
1
解决办法
253
查看次数

JFrame永远不会被垃圾收集

我有一个需要打开多个JFrame的应用程序(它是一个日志查看器,有时您需要在单独的窗口中查看一堆日志来进行比较).

似乎JVM(OS X上的Java 8更新101)持有对JFrame的强引用,这阻止了它被垃圾收集,并最终导致抛出OutOfMemoryError.

若要查看该问题,请运行此问题,最大堆大小为200 MB.每次打开一个窗口时,它都会消耗50兆字节的RAM.打开三个窗口(使用150兆字节的RAM).然后关闭三个窗口(调用dispose),这将释放内存.然后尝试打开第四个窗口.抛出OutOfMemoryError,第四个窗口无法打开.

我已经看到了其他答案,说明在必要时会自动释放内存以避免耗尽,但这似乎并没有发生.

package com.prosc.swing;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;

public class WindowLeakTest {
    public static void main(String[] args) {
        EventQueue.invokeLater( new Runnable() {
            public void run() {
                JFrame launcherWindow = new JFrame( "Launcher window" );
                JButton launcherButton = new JButton( "Open new JFrame" );
                launcherButton.addActionListener( new ActionListener() {
                    public void actionPerformed( ActionEvent e ) {
                        JFrame subFrame = new JFrame( "Sub frame" ) {
                            private byte[] bigMemoryChunk = new byte[ …
Run Code Online (Sandbox Code Playgroud)

java swing java-memory-leaks

1
推荐指数
1
解决办法
691
查看次数