java - 如何从内存中删除变量?
问题描述
将文件转换为字节时,不应使用 Files.readAllBytes 类。使用不同的字节转换器后。主要问题是变量中的字节数组无法从内存中删除。
示例 1
byte[] x1=new byte[50];
x1=null; //not memory deleting;
示例 2
byte[] x2=null; //memory space:0
x2=new byte[50]; //memory space:50
x2=new byte[100]; //memory space:150
x2=new byte[10]; //memory space:160
x2=null; //memory space:160
我意识到情况就是这样。
我们如何从内存空间中清除它?C语言(Malloc)中有动态内存分配方法,java中不会删除这个内存。
package dragdrop;
import java.awt.EventQueue;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.TransferHandler;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class gfgh {
private JFrame frame;
private File_Class file_Class=null;
private JPanel panel;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
gfgh window = new gfgh();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public gfgh() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
panel.setBackground(Color.BLACK);
frame.getContentPane().add(panel, BorderLayout.CENTER);
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
memorydelete();
}
});
panel.add(btnNewButton);
this.DragDrop(panel);
}
private void DragDrop(JComponent component)
{
@SuppressWarnings("serial")
TransferHandler transferHandler=new TransferHandler(){
@Override
public boolean canImport(JComponent component,DataFlavor[] dataFlavor)
{
return true;
}
@SuppressWarnings("unchecked")
@Override
public boolean importData(JComponent comp, Transferable t) {
// TODO Auto-generated method stub
List<File> files;
try {
files = (List<File>) t.getTransferData(DataFlavor.javaFileListFlavor);
for(File file:files)
{
System.out.println(file.getAbsolutePath());
System.out.println(file.length());
file_Class=new File_Class();
//file read examle 1 false
// file_Class.file=Files.readAllBytes(Paths.get(file.getAbsolutePath()));
//* file read example 2 false
/*
RandomAccessFile f = new RandomAccessFile(file.getAbsolutePath(), "r");
file_Class.file = new byte[(int)f.length()];
f.readFully( file_Class.file);
*/
//example 3 false
// file_Class.file=readFile(file);
//example 4 false
file_Class.file=readFile(file);
memorydelete();
///////
}
files=null;
Runtime.getRuntime().gc();
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
};
component.setTransferHandler(transferHandler);
}
public void memorydelete()
{
file_Class.file=null;
file_Class=null;
Runtime.getRuntime().gc();
}
public static byte[] readFile(File file) throws IOException {
// Open file
RandomAccessFile f = new RandomAccessFile(file, "r");
try {
// Get and check length
long longlength = f.length();
int length = (int) longlength;
if (length != longlength)
throw new IOException("File size >= 2 GB");
// Read file and return data
byte[] data = new byte[length];
f.readFully(data);
return data;
} finally {
f.close();
}
}
}
class File_Class {
public byte file[];
}
解决方案
主要问题是变量中的字节数组无法从内存中删除。
不,这不是问题。
您需要做的就是通过分配null
给变量 ... 和任何其他仍保留对数组的引用的可访问变量来安排字节数组不可访问。
垃圾收集器 (GC) 会处理它。
你不需要打电话System.gc()
。GC 将在需要运行时运行。如果你尝试干预,你可能只会让你的代码效率低下。
真正的问题是以下之一:
文件太大,无法读入内存;即大到你得到一个OOME。如果是这种情况,解决方案是流式传输文件而不是使用
readAllBytes
.您正在沉迷于内存利用率。内存很便宜。程序员的时间很昂贵。
如果您确实需要最小化应用程序的内存使用量,那么您使用的编程语言是错误的。Java 不是为这种编程风格而设计的。Java 和 Java 垃圾收集器被设计为在 GC 不经常运行并且有足够的空闲内存在收集之间保存垃圾的情况下高效。如果您试图与之抗争,您的应用程序很可能会浪费大量时间来回收少量内存。
请注意,即使 Java GC 确实(几乎)立即收集了您无法访问的字节数组,它也可能不会将回收的内存返回给操作系统。所以你的应用程序的内存占用不会缩小。因此,您很可能不会从显式调用中获得任何System.gc()
真正的好处。
如果您确实需要最小化内存使用量,请使用 C 或 C++
如果您确实需要显式删除对象,请使用 C 或 C++
推荐阅读
- groovy - 我可以保持 Groovy 电源断言并且仍然打印自定义消息吗?
- java - 通用 Xml/JSON 解析器(最好是 SAX 或 STAX):根据每个不同的 xml 格式通过配置文件提供节点/xpath 信息
- react-native - 反应原生 Azure Iothub 客户端
- javascript - 如何拥有多色折线谷歌地图
- mysql - 如何从db中选择ip?
- angular - 使用 angular-azure-blob-service 时出现 403 错误
- swift - 使用参数以编程方式创建表视图 - swift
- ios - 如何将 GPS 坐标导航到 CameraView
- mongodb - 可以在 mongoDB Shard 集群中进行增量备份吗?没有 opsmanager
- batch-file - 批处理脚本在操作系统和 Winpe 环境中执行时给出不同的输出