如何从内存中删除变量?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从内存中删除变量?相关的知识,希望对你有一定的参考价值。
将文件转换为字节时,不应使用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[];
}
在Java中,数组是对象。 Java垃圾收集器最终将处理它们,并将回收与未引用对象关联的内存。
您可以轻松地对此进行如下测试:
public class Test {
public static void main(String[] args) {
long m1 = Runtime.getRuntime().freeMemory();
byte[] data = new byte[1024*1024*4];
long m2 = Runtime.getRuntime().freeMemory();
data = null;
System.gc();
long m3 = Runtime.getRuntime().freeMemory();
System.out.println("m1: " + m1);
System.out.println("m2: " + m2);
System.out.println("m3: " + m3);
}
}
输出(绝对值在您的环境中会有所不同):
m1: 15887208
m2: 11692888
m3: 15972272
如您所见,在这里明确触发垃圾回收将回收与4 MB字节数组关联的资源。现在,通常不需要显式地触发垃圾收集器,也不需要生产性/高效的(实际上没有保证可以触发垃圾收集器)。在示例中,此操作仅出于说明目的。
垃圾回收在后台运行,JVM对其进行调度以使其适合您。一种策略是在(几乎)耗尽堆空间时运行完整集合。事情变得更加复杂,因为不同代的对象通常存在不同种类的堆(例如,新对象与旧对象)。
您可以做的最重要的事情就是不要保留对未使用对象的引用。最终,那些未引用的对象将被收集,并且相关的内存将被重用。
主要问题是变量中的字节数组无法从内存中删除。
没有那不是问题。
[您需要做的是通过将null
分配给变量...以及其他仍可引用该数组的可到达变量,来安排字节数组不可访问。
垃圾收集器(GC)将处理它。
您无需致电System.gc()
。 GC将在需要运行时运行。如果尝试干预,则可能只会使代码效率低下。
真正的问题是下列之一:
文件太大不能读入内存;即太大,您将获得一个OOME。如果是这种情况,解决方案是流式传输文件而不是使用
readAllBytes
。您对内存使用率感到困扰。内存很便宜。编程时间很昂贵。
如果确实
需要
System.gc()
中获得any
真正的好处。如果确实需要
以最大程度地减少内存使用,请使用C或C ++如果确实需要
显式删除对象,请使用C或C ++以上是关于如何从内存中删除变量?的主要内容,如果未能解决你的问题,请参考以下文章