「java全局异常日志记录」记录异常的日志

博主:adminadmin 2022-12-06 22:24:07 61

今天给各位分享java全局异常日志记录的知识,其中也会对记录异常的日志进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

Java编程:常见的几个错误

Java 中最常见的 5 个错误:

1、Null 的过度使用

避免过度使用 null 值是一个最佳实践。例如,更好的做法是让方法返回空的 array 或者 collection 而不是 null 值,因为这样可以防止程序抛出 NullPointerException。

2、忽视异常

我们经常对异常置之不理。然而,针对初学者和有经验的 Java 程序员,最佳实践仍是处理它们。异常抛出通常是带有目的性的,因此在大多数情况下需要记录引起异常的事件。别小看这件事,如果必要的话,你可以重新抛出它,在一个对话框中将错误信息展示给用户或者将错误信息记录在日志中。至少,为了让其它开发者知晓前因后果,你应该解释为什么没有处理这个异常。

3、并发修改异常

这种异常发生在集合对象被修改,同时又没有使用 iterator 对象提供的方法去更新集合中的内容。

4、违约

有时候,为了更好地协作,由标准库或者第三方提供的代码必须遵守共同的依赖准则。例如,必须遵守 hashCode和equals的共同约定,从而保证 Java 集合框架中的一系列集合类和其它使用hashCode和equals方法的类能够正常工作。不遵守约定并不会产生 exception 或者破坏代码编译之类的错误;它很阴险,因为它随时可能在毫无危险提示的情况下更改应用程序行为。

5、使用原始类型而不是参数化的

根据 Java 文档描述:原始类型要么是非参数化的,要么是类 R 的(同时也是非继承 R 父类或者父接口的)非静态成员。在 Java 泛型被引入之前,并没有原始类型的替代类型。Java 从1.5版本开始支持泛型编程,毫无疑问这是一个重要的功能提升。然而,由于向后兼容的原因,这里存在一个陷阱可能会破坏整个类型系统。

Android 捕获全局异常CrashHandler,防止异常闪退,记录异常日志

import android.content.Context;

import android.content.pm.PackageInfo;

import android.content.pm.PackageManager;

import android.content.pm.PackageManager.NameNotFoundException;

import android.os.Build;

import android.os.Looper;

import android.widget.Toast;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.lang.Thread.UncaughtExceptionHandler;

import java.lang.reflect.Field;

import java.util.HashMap;

import java.util.Map;

/**

* UncaughtException handler class

*

*/

public class CrashHandler implements UncaughtExceptionHandler {

public static final String TAG = "CrashHandler";

public static final String PROGRAM_BROKEN_ACTION = "com.teligen.wccp.PROGRAM_BROKEN";

private UncaughtExceptionHandler mDefaultHandler;

private static CrashHandler instance = new CrashHandler();

private Context mContext;

private Class? mainActivityClass;

private MapString, String infos = new HashMapString, String();

private CrashHandler() {

}

public static CrashHandler getInstance() {

return instance;

}

public void init(Context context, Class? activityClass) {

mContext = context;

this.setMainActivityClass(activityClass);

mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();

Thread.setDefaultUncaughtExceptionHandler(this);

}

@Override

public void uncaughtException(Thread thread, Throwable ex) {

if (!handleException(ex) mDefaultHandler != null) {

mDefaultHandler.uncaughtException(thread, ex);

} else {

System.out.println("uncaughtException---" + ex.getMessage());

// Log.e(TAG, ex.getMessage());

logError(ex);

try {

Thread.sleep(3000);

} catch (InterruptedException e) {

// Log.e("debug", "error:", e);

}

exitApp();

}

}

private boolean handleException(Throwable ex) {

if (ex == null) {

return false;

}

new Thread(new Runnable() {

@Override

public void run() {

Looper.prepare();

Toast.makeText(mContext.getApplicationContext(),

"unknown exception and exiting...Please checking logs in sd card!", Toast.LENGTH_LONG).show();

Looper.loop();

}

}).start();

collectDeviceInfo(mContext.getApplicationContext());

logError(ex);

return true;

}

private void exitApp() {

android.os.Process.killProcess(android.os.Process.myPid());

System.exit(0);

}

public void collectDeviceInfo(Context ctx) {

try {

PackageManager pm = ctx.getPackageManager();

PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),

PackageManager.GET_ACTIVITIES);

if (pi != null) {

String versionName = pi.versionName == null ? "null"

: pi.versionName;

String versionCode = pi.versionCode + "";

infos.put("versionName", versionName);

infos.put("versionCode", versionCode);

}

} catch (NameNotFoundException e) {

e.printStackTrace();

}

Field[] fields = Build.class.getDeclaredFields();

for (Field field : fields) {

try {

field.setAccessible(true);

infos.put(field.getName(), field.get(null).toString());

} catch (Exception e) {

}

}

}

private void logError(Throwable ex) {

StringBuffer sb = new StringBuffer();

for (Map.EntryString, String entry : infos.entrySet()) {

String key = entry.getKey();

String value = entry.getValue();

sb.append(key + "=" + value + "\n");

}

int num = ex.getStackTrace().length;

for (int i=0;inum;i++){

sb.append(ex.getStackTrace()[i].toString());

sb.append("\n");

}

File file = new File(filePath+"/log.txt");

FileOutputStream fos = null;

try {

fos = new FileOutputStream(file);

fos.write((sb.toString()+"exception:"+ex.getLocalizedMessage()).getBytes());

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}finally {

try {

fos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

public Class? getMainActivityClass() {

return mainActivityClass;

}

public void setMainActivityClass(Class? mainActivityClass) {

this.mainActivityClass = mainActivityClass;

}

}

filePath是记录日志的路径

在Applicaton中初始化

@Override

public void onCreate() {

    super.onCreate();

    CrashHandler mCrashHandler = CrashHandler.getInstance();

    mCrashHandler.init(getApplicationContext(), getClass());

    initFile();

}

JAVA程序设计,多线程且避免死锁

JAVA中几种常见死锁及对策:解决死锁没有简单的方法,这是因为线程产生死锁都各有各的原因,而且往往具有很高的负载。大多数软件测试产生不了足够多的负载,所以不可能暴露所有的线程错误。在这里中,下面将讨论开发过程常见的4类典型的死锁和解决对策。(1)数据库死锁在数据库中,如果一个连接占用了另一个连接所需的数据库锁,则它可以阻塞另一个连接。如果两个或两个以上的连接相互阻塞,则它们都不能继续执行,这种情况称为数据库死锁。数据库死锁问题不易处理,通常数据行进行更新时,需要锁定该数据行,执行更新,然后在提交或回滚封闭事务时释放锁。由于数据库平台、配置的隔离级以及查询提示的不同,获取的锁可能是细粒度或粗粒度的,它会阻塞(或不阻塞)其他对同一数据行、表或数据库的查询。基于数据库模式,读写操作会要求遍历或更新多个索引、验证约束、执行触发器等。每个要求都会引入锁。此外,其他应用程序还可能正在访问同一数据库模式中的某些对象,并获取不同应用程序所具有的锁。所有这些因素综合在一起,数据库死锁几乎不可能被消除了。值得庆幸的是,数据库死锁通常是可恢复的:当数据库发现死锁时,它会强制销毁一个连接(通常是使用最少的连接),并回滚其事务。这将释放所有与已经结束的事务相关联的锁,至少允许其他连接中有一个可以获取它们正在被阻塞的锁。由于数据库具有这种典型的死锁处理行为,所以当出现数据库死锁问题时,数据库常常只能重试整个事务。当数据库连接被销毁时,会抛出可被应用程序捕获的异常,并标识为数据库死锁。如果允许死锁异常传播到初始化该事务的代码层之外,则该代码层可以启动一个新事务并重做先前所有工作。当出现问题就重试,由于数据库可以自由地获取锁,所以几乎不可能保证两个或两个以上的线程不发生数据库死锁。此方法至少能保证在出现某些数据库死锁情况时,应用程序能正常运行。(2)资源池耗尽死锁客户端的增加导致资源池耗尽死锁是由于负载而造成的,即资源池太小,而每个线程需要的资源超过了池中的可用资源。假设连接池最多有10个连接,同时有10个对外部并发调用。这些线程中每一个都需要一个数据库连接用来清空池。现在,每个线程都执行嵌套的调用。则所有线程都不能继续,但又都不放弃自己的第一个数据库连接。这样,10个线程都将被死锁。研究此类死锁,会发现线程存储中有大量等待获取资源的线程,以及同等数量的空闲且未阻塞的活动数据库连接。当应用程序死锁时,如果可以在运行时检测连接池,就能确认连接池实际上已空。修复此类死锁的方法包括:增加连接池的大小或者重构代码,以便单个线程不需要同时使用很多数据库连接。或者可以设置内部调用使用不同的连接池,即使外部调用的连接池为空,内部调用也能使用自己的连接池继续。(3)单线程、多冲突数据库连接死锁对同一线程执行嵌套的调用有时出现死锁,此情形即使在非高负载系统中通常也会发生。当第一个(外部)连接已获取第二个(内部)连接所需要的数据库锁,则第二个连接将永久阻塞第一个连接,并等待第一个连接被提交或回滚,这就出现了死锁情形。因为数据库没有注意到两个连接之间的关系,所以数据库不会将此情形检测为死锁。这样即使不存在并发,此代码也将导致死锁。此情形有多种具体的变种,可以涉及多个线程和两个以上的数据库连接。(4)Java虚拟机锁与数据库锁冲突这种情形发生在数据库锁与Java虚拟机锁并存的时候。在这种情况下,一个线程占有一个数据库锁并尝试获取Java虚拟机锁。同时,另一个线程占有Java虚拟机锁并尝试获取数据库锁。此时,数据库发现一个连接阻塞了另一个连接,但由于无法阻止连接继续,所以不会检测到死锁。Java虚拟机发现同步的锁中有一个线程,并有另一个尝试进入的线程,所以即使Java虚拟机能检测到死锁并对它们进行处理,它还是不会检测到这种情况。 总而言之,JAVA应用程序中的死锁是一个大问题——它能导致整个应用程序慢慢终止,还很难被分离和修复,尤其是当开发人员不熟悉如何分析死锁环境的时候。五.死锁的经验法则笔者在开发中总结以下死锁问题的经验。(1)对大多数的Java程序员来说最简单的防止死锁的方法是对竞争的资源引入序号,如果一个线程需要几个资源,那么它必须先得到小序号的资源,再申请大序号的资源。可以在Java代码中增加同步关键字的使用,这样可以减少死锁,但这样做也会影响性能。如果负载过重,数据库内部也有可能发生死锁。(2)了解数据库锁的发生行为。假定任何数据库访问都有可能陷入数据库死锁状况,但是都能正确进行重试。例如了解如何从应用服务器获取完整的线程转储以及从数据库获取数据库连接列表(包括互相阻塞的连接),知道每个数据库连接与哪个Java线程相关联。了解Java线程和数据库连接之间映射的最简单方法是向连接池访问模式添加日志记录功能。(3)当进行嵌套的调用时,了解哪些调用使用了与其它调用同样的数据库连接。即使嵌套调用运行在同一个全局事务中,它仍将使用不同的数据库连接,而不会导致嵌套死锁。(4)确保在峰值并发时有足够大的资源池。(5)避免执行数据库调用或在占有Java虚拟机锁时,执行其他与Java虚拟机无关的操作。 最重要的是,多线程设计虽然是困难的,但在开始编程之前详细设计系统能够帮助你避免难以发现死锁的问题。死锁在语言层面上不能解决,就需要一个良好设计来避免死锁。

下载java虚拟机启动器发现致命异常怎么回事.

修复Java虚拟机错误的解决方案:

1.为Java设置新的系统变量

当Java需要更大的全局最大堆内存大小时,通常会出现Java虚拟机错误。通过扩展分配给Java的最大RAM来解决该问题。用户可以通过建立新的Java System Variable来实现,如下所示。

使用Windows键+ R键盘快捷键打开运行。

在“运行”中输入“sysdm.cpl”,然后单击“ 确定”以在下面的图像中打开窗口。

选择该窗口上的“高级”选项卡。

单击“ 环境变量”按钮以打开下面的窗口。

单击“ 系统变量”框下的“ 新建”按钮。

在“变量名称”文本框中输入“_JAVA_OPTIONS”。

然后在“变量值”文本框中输入“-Xmx512M”,这会将RAM分配增加到512 MB。

单击“ 确定”按钮关闭窗口。

然后按环境窗口上的确定按钮。

2.选择“以管理员身份运行Java选项”

Java虚拟机错误也可能是由于管理员权限不足造成的。因此,某些用户可能需要为Java分配管理员权限。用户可以在Windows 10中为Java分配管理员权限,如下所示。

使用Windows键+ Q键盘快捷键打开Cortana。

在搜索框中输入“Java”。

然后右键单击Java并选择打开文件位置以在文件资源管理器中打开Java的文件夹。

现在,用户可以右键单击java.exe并选择“ 属性”。

选择兼容性选项卡。

选择“以管理员身份运行此程序”选项。

选择“ 应用”选项。

单击“ 确定”关闭窗口。

3.重新安装Java

重新安装Java也可能会修复某些用户的Java虚拟机错误。首先,在“运行”中输入“appwiz.cpl”并单击“ 确定 ” ,卸载当前安装的Java版本。

在搜索框中输入“Java”。

选择Java,然后单击卸载。

在打开的任何确认窗口中单击是。

此后,重新启动Windows。

然后在浏览器中打开Java下载页面。

用户需要32位Java用于32位程序,64位Java用于64位软件。如果有疑问,最好的办法是通过单击Windows Offline和Windows Offline 64位来下载和安装两个Java版本。

此后,打开Java安装向导。

单击安装向导上的“ 安装”按钮。

java全局异常日志记录的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于记录异常的日志、java全局异常日志记录的信息别忘了在本站进行查找喔。

The End

发布于:2022-12-06,除非注明,否则均为首码项目网原创文章,转载请注明出处。