ENV:
JDK:1.8u112神谕
JRE:10.0.2
JVM最大堆大小:〜2GB。
操作系统:Windows 10
IDE:Netbeans的8.1
内存:8GB DDR4
处理器:酷睿i7 6700hq英特尔
上下文
一个简单的GUI打开的图像文件(JPG / PNG)和经由用户输入放大它。
说明
一类扩展JFrame的。 该框架的contentPane中有一个JButton,一个JLabel和一个JScrollPane。 单击该按钮将显示一个JFileChooser。 标签是滚动窗格内。 选择一个文件(仅适用于测试这个问题,JPG / PNG的目的,打开图像文件)打开它的标签。 该标签具有的鼠标滚轮侦听使经由缩放图像的Image.getScaledInstance
。 在每个变焦,magnifiaction(新的图像宽度(或高度的比),对应的原始的)和Runtime.totalMemory
被打印。
问题
- 在缩放到图像,太多的记忆,似乎正由代码所消耗。 任务管理器显示11.8倍的放大倍率1708 MB内存使用量为7.23KB PNG图像。 预计应该在11.8 * 11.8 * 7.23KB顺序
- 在缩小,内存消耗不会减少
- 为什么堆扩大这么多(大约〜17次MAG,达到2GB)摆在首位? 被丢弃
ImageIcon
对象(见代码)不是gced? - 如何使代码可行的MAG,其中MAG美格* * originalImageSize(以字节为单位)<50%的最大JVM堆大小?
码
import java.awt.Dimension;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class gui extends javax.swing.JFrame {
Image image;
Dimension size;
private double mag = 1;
Runtime runtime = Runtime.getRuntime();
public gui() {
initComponents();
}
private void zoom() {
int[] newSize = {(int) (size.width * mag), (int) (size.height * mag)};
if (newSize[0] > 0 && newSize[1] > 0) {
label.setIcon(new ImageIcon(image.getScaledInstance(newSize[0], newSize[1], Image.SCALE_DEFAULT)));
}
System.out.println("mag:" + (int) (mag * 100) + "% mem:" + runtime.totalMemory() / 1024 / 1024 + "MB");
}
private void loadImage(File imgFile) throws IOException {
String path = imgFile.getPath().toLowerCase();
if (path.endsWith("gif")) {
ImageIcon icon = new ImageIcon(path);
image = icon.getImage();
label.setIcon(icon);
} else {
image = ImageIO.read(imgFile);
ImageIcon icon = new ImageIcon(image);
label.setIcon(icon);
}
size = new Dimension(image.getWidth(null), image.getHeight(null));
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
dialog = new javax.swing.JFileChooser();
jScrollPane1 = new javax.swing.JScrollPane();
label = new javax.swing.JLabel();
button = new javax.swing.JButton();
dialog.setCurrentDirectory(new java.io.File("D:\\"));
dialog.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
dialogActionPerformed(evt);
}
});
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Image Viewer");
label.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
label.setVerticalAlignment(javax.swing.SwingConstants.TOP);
label.addMouseWheelListener(new java.awt.event.MouseWheelListener() {
public void mouseWheelMoved(java.awt.event.MouseWheelEvent evt) {
labelMouseWheelMoved(evt);
}
});
jScrollPane1.setViewportView(label);
button.setText("open");
button.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
buttonActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 689, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(button)
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(button)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE)
.addContainerGap())
);
pack();
}// </editor-fold>
private void dialogActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
if (evt.getActionCommand().equals(JFileChooser.APPROVE_SELECTION)) {
try {
File file = dialog.getSelectedFile();
loadImage(file);
setTitle(file.getPath());
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
private void labelMouseWheelMoved(java.awt.event.MouseWheelEvent evt) {
if (image != null) {
int amt = -evt.getWheelRotation();
double newMag = mag + amt * 0.1;
if (newMag > 0) {
mag = newMag;
zoom();
}
}
}
private void buttonActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
dialog.showOpenDialog(this);
}
public static void main(String args[]) throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new gui().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton button;
private javax.swing.JFileChooser dialog;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JLabel label;
// End of variables declaration
}
测试文件
任何JPG或PNG图片应该做的,除了测试文件 。
从测试文件输出
MAG:110%MEM:123MB MAG:120%MEM:123MB MAG:130%MEM:123MB MAG:140%MEM:123MB MAG:150%MEM:123MB MAG:160%MEM:123MB MAG:150%MEM:123MB MAG :160%MEM:123MB MAG:170%MEM:123MB MAG:180%MEM:155MB MAG:190%MEM:155MB MAG:200%MEM:155MB MAG:210%MEM:155MB MAG:220%MEM:155MB MAG: 230%MEM:157MB MAG:240%MEM:157MB MAG:250%MEM:157MB MAG:260%MEM:157MB MAG:270%MEM:253MB MAG:280%MEM:253MB MAG:290%MEM:253MB MAG:300 %MEM:253MB MAG:310%MEM:253MB MAG:320%MEM:256MB MAG:330%MEM:256MB MAG:340%MEM:256MB MAG:350%MEM:256MB MAG:360%MEM:256MB MAG:370% MEM:393MB MAG:380%MEM:393MB MAG:390%MEM:393MB MAG:400%MEM:393MB MAG:410%MEM:393MB MAG:420%MEM:393MB MAG:430%MEM:466MB MAG:440%MEM :466MB MAG:450%MEM:466MB MAG:460%MEM:466MB MAG:470%MEM:466MB MAG:480%MEM:466MB MAG:489%MEM:541MB MAG:499%MEM:541MB MAG:509%MEM: 541MB MAG:519%MEM:541MB MAG:529%MEM:541MB MAG:539%MEM:641MB MAG:549%MEM:641MB MAG:559%MEM:641MB MAG:569%MEM:641MB MAG:579%MEM:641MB MAG:589%MEM:825MB MAG:599%MEM:825MB MAG:609%MEM :825MB MAG:619%MEM:825MB MAG:609%MEM:825MB MAG:619%MEM:825MB MAG:629%MEM:892MB MAG:639%MEM:892MB MAG:649%MEM:892MB MAG:659%MEM: 892MB MAG:669%MEM:892MB MAG:679%MEM:892MB MAG:689%MEM:881MB MAG:699%MEM:881MB MAG:709%MEM:881MB MAG:719%MEM:881MB MAG:729%MEM:1029MB MAG:739%MEM:1029MB MAG:749%MEM:1029MB MAG:759%MEM:1029MB MAG:769%MEM:1104MB MAG:779%MEM:1104MB MAG:789%MEM:1104MB MAG:799%MEM:1104MB MAG :809%MEM:1075MB MAG:819%MEM:1075MB MAG:829%MEM:1075MB MAG:839%MEM:1182MB MAG:849%MEM:1182MB MAG:859%MEM:1182MB MAG:869%MEM:1289MB MAG: 879%MEM:1289MB MAG:889%MEM:1542MB MAG:899%MEM:1542MB MAG:909%MEM:1542MB MAG:919%MEM:1569MB MAG:929%MEM:1569MB MAG:939%MEM:1569MB MAG:949 %MEM:1480MB MAG:959%MEM:1480MB MAG:969%MEM:1548MB MAG:979%MEM:1548MB MAG:989%MEM:1655MB MAG:999%MEM:1655MB MAG:1009%MEM:1707MB MAG:1019% MEM:1707MB MAG:1029%MEM:1802MB MAG:1039%MEM:1850MB MAG:1049%MEM:1850MB MAG:1059%MEM:1871MB MAG:1069%MEM:1871MB MAG:1079%MEM:1801MB MAG:1089%MEM :1862 MB MAG:1099%MEM:1862MB MAG:1109%MEM:1815MB MAG:1119%MEM:1822MB MAG:1129%MEM:1758MB MAG:1139%MEM:1774MB MAG:1149%MEM:1711MB MAG:1159%MEM:1734MB MAG:1169%MEM:1676MB MAG:1179%MEM:1708MB MAG:1189%MEM:1654MB