java - 将 Swing 应用程序从 Java 6 迁移到 Java 7 Update 11 时运行时内存增加

标签 java swing memory java-web-start

一旦 Java Swing 应用程序从 Java 6 32 位迁移到 Java 7 32 位更新 11,我们将面临性能问题。谁能提供一些线索?

应用程序使用 Java Web-start 技术,服务器是 Tomcat 7。客户端应用程序正在消耗 1GB 内存,因此屏幕卡住。

我们正在交换序列化的对象,代码如下:

Object object = connection.sendCommand(command); // exchanging serialized object            

public class ConnectionImpl implements Connection {
    public Object sendCommand(Command command) throws Exception {
        URL url = new URL(System.getProperty("serverUrl"));
        URLConnection connection = url.openConnection();
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setUseCaches(false);
        oos = new ObjectOutputStream(new BufferedOutputStream(connection
                    .getOutputStream()));
        oos.writeObject(command);
        oos.flush();
        InputStream inputStream = connection.getInputStream();
        ZipInputStream zip = new ZipInputStream(inputStream);
        if (zip.getNextEntry() != null) {
            ois = new ObjectInputStream(zip);
            object = ois.readObject();
        }
        zip.close();
    }
}

// The serialized class
public class CommandImpl implements Command, Serializable {
    private String serviceName;
    private String methodName;
    private Map<String, Object> parameterMap;

// followed by getter & setters
}
  • 客户端机器: Windows 7 32 位,Java 7 更新 11 32 位
  • 服务器机器: Windows 64 bit 2008 R2 Enterprise Server,Java 7 update 11 64 bit

代码没有变化,只是更新了JVM。

我使用 Java VisualVM 为 JDK 1.6 和 JDK 1.7 拍摄了内存快照,以下是包含快照的 rar 文件的链接:

Memory Snapshots using Java VisualVM Heap Dump using Java VisualVM

NetBeans IDE 提供了将代码从 Java 6 迁移到 Java 7 的选项。以下是与此相关的链接:

https://netbeans.org/kb/docs/java/editor-inspect-transform.html#convert

将整个源代码从 Java 6 迁移到 Java 7 不会出现任何问题吗?或者有人觉得这可能会产生一些问题?如果我们这样做,我们是否可以在某种程度上解决这个性能问题?

最佳答案

ObjectOutputStream oos 是在方法中构造的,但看起来您从未关闭过它。关闭流将释放内存。

ObjectOutputStream 何时收集垃圾? ObjectOutputStream and ObjectInputStream keep read and written objects in memory .这看起来像是内存泄漏。

我建议您添加 finally block 以确保 Streams 被关闭。 我无法从您发布的内容中判断序列化对象的生命周期,但您可能会从使用 readUnshared 和 writeUnshared 方法中受益。

你写道:

Will it be a good option for migrating the entire source code from Java 6 to Java 7 without any issue? Or anyone feels that it might create some issue ? And if we do so, whether we can solve this performance issue up-to some extend?

您不会从使用工具将代码更新到 1.7 中受益。如果你这样做了,你将不再能够在 1.6 中运行你的代码。我建议运行 Netbean 的“性能”检查。此外,我强烈建议对您的代码库运行 FindBugs。

堆转储

  • jdk 1.7 转储在使用 53M 时从堆中取出。
  • jdk 1.6 转储是在使用 61M 时进行的。

您发布的堆转储并没有太大帮助,因为它们看起来像是在内存出现问题之前就已被使用。 您需要在系统使用大量内存时进行堆转储,以便您可以检查转储并找出正在使用内存的位置。

添加 -XX:+HeapDumpOnOutOfMemoryError jvm 选项。使用此选项,java 将在内存不足时自动获取自己的 heapdump。

快照

** 尽管您的快照存档中有四个文件,但其中两个文件是重复的,但名称不同。查看大小和校验和,您会发现它们是相同的。 **

这些快照信息量更大,但它们似乎也是在使用大量内存之前拍摄的。

1.7 的快照有更多的 String 实例。

1.6 的快照如下所示: visualvm iamge

1.7 的快照如下所示: enter image description here

String.substring no longer shares an underlying character array .这对于执行大量字符串操作的代码来说可能是一个很大的不同。

那些 char[] 将实际数据保存在您的 String 对象中。我会仔细看看哪些对象包含字符串以及这些字符串是如何构造的。

关于java - 将 Swing 应用程序从 Java 6 迁移到 Java 7 Update 11 时运行时内存增加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16983309/

相关文章:

java - log4j - 空日志文件 -

c++ - Double 或 int 的 Printf

c++ - 使用常量长度时 char[] 和 new char[] 之间的区别

c++ - 代码arp数组、指针和内存分配的不可理解部分(Windows IP函数)

java - 如何在管道传输到/从 javas stdin/stdout 时捕获错误

java - 使用 Double 以相反的顺序对 HashMap 进行排序

java - 如何通过动态数组或 ArrayList 使用数据库中的值填充 JTable

java - 从 Java 执行 lisp 函数

Java、JFC、 Swing

java - 使用 Java 流简化列表,其中每个元素本身都是映射列表